2016-07-13 6 views
3

postDelayedとメインスレッドで実行される他のコードを使用するコードがあります。私はそれを数回実行し、常に次のような出力を見た:Androidで実際に実行されるpostDelayedにランナビがいつ掲載されますか?

7月13日14:22:18.511 15376から15376/sample1.com.sample_1のD/MainActivityを: = 0

私を... 22:..

07から13 14 18.601 15376から15376/sample1.com.sample_1のD/MainActivity: onResume 7月13日14:22:18.601 15376から15376/sample1.com.sample_1 D/MainActivity :私のよう

をpostDelayedログ出力から見ると、私の遅延は50ミリ秒であることは関係ありません。メッセージ「postDelayed」は、約100ミリ秒後に入力されます(601-511 = 90)。 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

他のサービスやアプリケーションからのログもあるため、ログ出力に基づいてハンドラの遅延を計算することは正しくありません。 Androidのログ記録メカニズムには独自のキューがあるため、メッセージがキュー内の他のログのために実際に遅延する可能性があります。

私の提案は、ハンドラの遅延の間の時間を計算するSystem.nanoTime()を使用することでしょう。私が知る限り、それは最も正確なタイマー値を与えます。

最後にノーアクションが行われる正確な時刻を特定することはできません、あなたの質問に答えます。アプリケーションの動作を遅延させる可能性のある数千(数百万ではないにせよ)のさまざまな条件があります(特に非同期アクションの場合)。

編集:この遅延は正確に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ナノ秒= 10 ms(約) –

0

使用post()実際に彼らは似ている、sendMessageDelayed(getPostMessage(r), 0)を呼び出し、postDelayed()sendMessageDelayed(getPostMessage(r), delayMillis)を呼び出します。

post...()のメソッドは、最終的にパラメータで異なるqueue.enqueueMessageを呼び出し、msgがメッセージキューのどこに挿入されるかを決定します。あなたはキュー内のmsgを変更することができますが、msgが実行されたことを中断することはできません。

1

Handler.postDelay()ダウンのためのコードをトレースした後、それが最終的にMessageQueue.enqueueMessage()が呼び出されるようになります。コードから、メッセージキューに最後まで到達するまで、または現在のタスクの時間が遅延時間よりも長くなるまで、メッセージキューを無限ループするように見えるし、タスクをキューのその位置に挿入します。これが意味することは、タスクが実行される場所よりも先にあるキューが非常に長くなっていることです。必要なときに数ミリ秒以内にタスクを実行する必要があります。

私はあなたの操作が問題ではないことを推測しているのではなく、Androidはあなたのタスクを遅らせているもので、あなたのUIや他の内部のジョブをレンダリングするメインスレッドで忙しいです。おそらく、onCreateonStartonResumeのすべてのコードをあなたのアクティビティ上で実行し、そのクラスが拡張したクラスはpostDelay時間+ 10msの前にキューに入れられていたでしょう。

100msは約6フレームですので、アクティビティのUIを表示するのに時間がかかることがあります。代わりにボタンクリックでpostDelayを実行すると、UIとアクティビティが予測可能になるはずですセットアップや解体はしていません。

+0

07-13 17:49:45.781 14332-14332/sample1.com.sample_1 D/MainActivity:I = 0 ..... 7月13日17:49:45.871 14332から14332/sample1.com.sample_1のD/MainActivity:postDelayed それは、ボタンのクリックにコードを移動するようになります 違いはありません –

関連する問題