2016-07-13 44 views
3

有一段代碼,我使用postDelayed和一些其他代碼在主線程上執行。我跑了幾次並總是看到下面的輸出:什麼時候發佈在postDelayed中的runnables實際上在Android上執行?

07-13 14:22:18.511 15376-15376/sample1.com.sample_1 d/MainActivity:ⅰ = 0

.. ..

07-13 14:22:18.601 15376-15376/sample1.com.sample_1 d/MainActivity: 的onResume 07-13 14:22:18.601 15376-15376/sample1.com.sample_1 d/MainActivity :postDelayed

因爲我從日誌輸出中看到,我的延遲是50毫秒並不重要。在大約100 ms(601 - 511 = 90)後鍵入消息「postDelayed」。看起來延遲的runnable被添加到我的UI線程的消息隊列的末尾。但無論如何,是否有關於何時完全postDelayed鍵入的任何保證?它可以在for循環的中間輸入嗎?

package sample1.com.sample_1; 

import android.os.Bundle; 
import android.os.Handler; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 

public class MainActivity extends AppCompatActivity { 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       Log.d("MainActivity", "postDelayed"); 
      } 
     }, 10); 
     for (int i = 0; i < 10000; i++) { 
      Log.d("MainActivity", "i = " + i); 
     } 
    } 

    @Override 
    protected void onResume() { 
     Log.d("MainActivity", "onResume"); 
     super.onResume(); 

    } 
} 
+0

Android限制主線程中的UI操作是爲了防止你想要做的事情。 – Harlan

+0

@哈龍,我不確定我是否理解你。 –

回答

2

也有來自其他服務和應用程序的日誌,因此根據日誌輸出計算Handler延遲將不正確。 Android上的日誌記錄機制有它自己的隊列,所以您的消息實際上可能由於隊列中的其他日誌而延遲。

我的建議是使用System.nanoTime()來計算Handler延遲之間的時間。據我所知,它提供了最精確的計時器值。

最後回答你的問題,不,你不能確定一個行動將發生的確切時間。有數千(如果不是數百萬)不同的條件可能會延遲你的應用程序的行爲,特別是如果它是異步行爲。

編輯:該延遲不能保證準確的50ms延遲,但它可以保證「至少」50ms的延遲。

+0

是的,它看起來像'postDelayed(r,10)'保證至少10毫秒。以下是nanoTime的示例https://gist.github.com/anonymous/70f301a06959f91b96302d6a6adddd6d –

+0

07-13 17:58:36.391 30902-30902/sample1.com.sample_1 D/MainActivity:timeHandler = 22583545657183 07-13 17: 58:36.281 30902-30902/sample1.com.sample_1 D/MainActivity:beforeTimeHandler = 22583437099224 diff是108557959 nanosec = 10 ms(大約) –

1

在追蹤Handler.postDelay()的代碼後,它看起來像最終調用了MessageQueue.enqueueMessage()。從代碼中,它似乎無限地循環通過消息隊列,直到達到最後,或者直到當前任務時間高於延遲時間,然後將任務插入隊列中的該位置。這意味着你的任務執行的地方之前的隊列需要很長的時間,你應該在幾毫秒內完成任務,而不是在你想要的時間內執行。

我猜你的操作不是問題,而是Android忙於主線程渲染你的UI和其他內部工作,這是延遲你的任務。據推測,在您的活動中執行onCreate,onStart,onResume中的所有代碼並將其擴展的類在postDelay時間+ 10ms之前排隊。

100ms大概是6幀,所以它可能只是顯示你的活動的UI的時間,嘗試執行你的postDelay而不是點擊按鈕,我相信時間會更容易預測,因爲UI和Activity是沒有被安裝或拆卸。

+0

07-13 17:49:45.781 14332-14332/sample1.com.sample_1 d/MainActivity中:i = 0 ..... 07-13 17:49:45.871 14332-14332/sample1.com.sample_1 d/MainActivity:postDelayed 它看起來像代碼移動到一個按鈕點擊沒有任何區別 –

相關問題