2017-05-20 11 views
0

例として、非同期的に呼び出されるdoDelayEventAとdoEventBという2つのメソッドがあるとします。簡単にするために、doDelayEventAは一度呼び出され、doEventBは一度呼び出されると仮定します。removeCallbacksAndMessagesはシリアル化されますか?

doDelayEventAはタイマー(実際にはハンドラ)を起動し、doEventBはそれを強制終了します(まだ保留中の場合)。

private Handler mTimer; 

    public void doDelayEventA(){ 
     mTimer = new Handler(); 
     mTimer.postDelayed(new Runnable() { 
      public void run() { 
       Log.d(LOG_TAG, "Event A: We want this to happen FIRST or not at all"); 
      } 
     }, 1000); 
    } 

    public void doEventB(){ 
     if (mTimer != null) { 
      mTimer.removeCallbacksAndMessages(null); 
     } 
     Log.d(LOG_TAG, "Event B: If it happens, it should ALWAYS happen LAST"); 
    } 

質問:実行可能を削除または実行されるまでremoveCallbacksAndMessagesシリアル化を強制しない、それは、それが実行をブロックされませんか?両方のメソッドが呼び出されたことを保証したいと思います。EventA Logステートメントは、EventB Logステートメントより先に常に実行されるか、まったく実行されません。

答えて

1

removeCallbacksAndMessagesはシリアル化を強制します。つまり、実行可能ファイルが削除または実行されるまで実行をブロックしますか? doEventB()は、メインアプリケーションスレッドで実行されている場合は

(または、より正確に、Handlerがに結びついているのと同じスレッド上で)、あなたはOKな形状にする必要があります。 HandlerはこれにMessageQueueを使用し、MessageQueueは少なくともAndroid 7.1にメッセージを同期的に削除します。しかし

  • これは、私の知る限りの行動を文書化し、そうありませんがなければならない一方で、あなたが、別のスレッドでdoEventB()を呼び出した場合、いくつかのリスクは、そのAndroidの振る舞いの他のバージョンが異なっ

  • がありますされていません競合状態が発生する可能性があります。doEventB()が1つのスレッドで呼び出され、Runnableが別のスレッドで実行を開始し、doEventB()ログメッセージがRunnableより前に発生します(たとえば、ConcurrentModificationException)。 gメッセージ

関連する問題