Я взял этот фрагмент с сайта, объясняющего обработчик в Android (потоковая передача).

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

          Thread myThread = new Thread(new Runnable() {
             @Override
             public void run() {
                for (int i = 0; i < 4; i++) {
                   try {
                      TimeUnit.SECONDS.sleep(2);
                   } catch (InterruptedException e) {
                      e.printStackTrace();
                   }
                   if (i == 2) {

                      mUiHandler.post(new Runnable() {
                         @Override
                         public void run() {
                            Toast.makeText(MyActivity.this, "I am at the middle of background task",
                                Toast.LENGTH_LONG)
                                .show();
                         }
                      });
                   }
                }//ends for()

               // THE SECOND HANDLER, RIGHT HERE!
                mUiHandler.post(new Runnable() {
                   @Override
                   public void run() {
                      Toast.makeText(MyActivity.this,
                          "Background task is completed",
                          Toast.LENGTH_LONG)
                          .show();
                   }
                });
             } //ends run()
          });
          myThread.start();

Судя по задаче, выданной во втором выполненном Handler, то есть

 Toast.makeText(MyActivity.this,
                      "Background task is completed",
                      Toast.LENGTH_LONG)
                      .show();

Похоже, автор статьи почти уверен, что второй Handler будет выполнен последним.

Мой вопрос в том, правда ли, что второй Handler будет выполняться последним сразу после того, как первый Handler завершит свою работу. Хотя, когда я запускал его несколько раз, да, он выполнялся последним. На мой взгляд, поскольку Handler выполняется в фоновом режиме Thread, мы не должны знать (даже предсказывать), какую из этих двух задач Handler выполнит в первую очередь. Мне нужно объяснение, заранее спасибо.

1
Plain_Dude_Sleeping_Alone 7 Сен 2016 в 14:18

3 ответа

Лучший ответ

Самый внешний анонимный Runnable, переданный конструктору new Thread(...), - это то, что выполняется в фоновом потоке. Все внутри этого runnable будет выполняться последовательно - одна инструкция за другой.

Поскольку этот runnable имеет цикл for, и только после этого появляется последний тост, вы гарантированно запускаете его после тела цикла.

1
orip 7 Сен 2016 в 11:28

Мой вопрос в том, правда ли, что второй обработчик будет выполняться последним сразу после того, как первый обработчик завершит свою работу.

Экземпляр Handler связан с одним Thread (также называемым очередью сообщений ).

Runnable выполняются на этом Thread последовательно.

Вызов post() поместит Runnable в конец этой очереди, так что да, второй Runnable будет выполнен после первого.

3
earthw0rmjim 7 Сен 2016 в 13:07

В игре задействованы не два обработчика, а только один обработчик в потоке пользовательского интерфейса (mUiHandler). Ваш вторичный поток создает объекты Runnable и размещает их в Handler. Они будут выполняться обработчиком в том порядке, в котором они были опубликованы. Поскольку цикл потока выполняется и публикуется первым, тогда поток завершается отправкой «второго» Runnable, второй всегда будет выполняться последним по сравнению с другими вещами, отправленными в цикле.

1
Larry Schiefer 7 Сен 2016 в 11:28