Что именно делает почтовый метод?

Я столкнулся с очень странной особенностью.

Когда я пытаюсь запустить анимацию в основном потоке, она не запускается. Когда я запускаю анимацию с помощью

getView().post(new Runnable() {
            @Override
            public void run() {
                getView().startAnimation(a);
            }
        });

Он начинается.

Я напечатал CurrentThread перед запуском анимации и напечатал main.

Очевидно, что я здесь что-то упускаю, так как оба должны начать анимацию по основному потоку... Я предполагаю, что, поскольку пост добавляет задачу в очередь, она начинается с более "правильного времени", но мне бы хотелось узнать, что здесь происходит на более глубокой глубине.

EDIT: Позвольте мне прояснить ситуацию - мой вопрос заключается в том, почему запуск анимации в сообщении заставляет ее начинать, когда запуск анимации в основном потоке не выполняется.

Ответ 1

post: post вызывает добавление Runnable в очередь сообщений,

Runnable: Представляет команду, которую можно выполнить. Часто используется для запуска кода в другом потоке.

run() : начинает выполнение активной части кода класса. Этот метод вызывается при запуске потока, созданного с помощью класса, который реализует Runnable.

getView().post(new Runnable() {

         @Override
         public void run() {
             getView().startAnimation(a);
         }
     });

код: getView().startAnimation(a);

в вашем коде,

сообщение заставляет Runnable (код будет запускаться в другом потоке), чтобы добавить очередь сообщений.

Таким образом, startAnimation будет запущен в новом потоке, когда он извлекается из messageQueue

[ОБНОВЛЕНИЕ 1]

Почему мы используем новый поток вместо потока пользовательского интерфейса (основной поток)?

Тема интерфейса:

  • Когда приложение запускается, поток пользовательского интерфейса создается автоматически

  • он отвечает за отправку событий в соответствующие виджеты и это включает в себя события рисования.

  • Это также нить, с которой вы взаимодействуете с виджетами Android с помощью

Например, если вы нажмете кнопку на экране, поток пользовательского интерфейса отправляет событие касания в виджет, который, в свою очередь, устанавливает его нажал состояние и отправляет недействительный запрос в очередь событий. Поток пользовательского интерфейса отменяет запрос и уведомляет виджет о перерисовке Сам.

Что произойдет, если пользователь нажмет кнопку, которая будет выполнять долгую операцию?

((Button)findViewById(R.id.Button1)).setOnClickListener(           
             new OnClickListener() {        
        @Override
    public void onClick(View v) {
            final Bitmap b = loadImageFromNetwork();
            mImageView.setImageBitmap(b);
}
});

Пользовательский интерфейс зависает. Программа может даже аварийно завершить работу.

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
        final Bitmap b = loadImageFromNetwork();
        mImageView.setImageBitmap(b);
    }
  }).start();
}

Это нарушает правило Android, согласно которому никогда не обновляет интерфейс непосредственно из рабочего потока

Android предлагает несколько способов доступа к потоку пользовательского интерфейса из других потоков.

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Обработчик

Как показано ниже,

View.post(Runnable)

public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      final Bitmap b = loadImageFromNetwork();
      mImageView.post(new Runnable() {
        public void run() {
          mImageView.setImageBitmap(b);
        }
      });
    }
  }).start();
}

Handler

final Handler myHandler = new Handler(Looper.getMainLooper());

(new Thread(new Runnable() {

    @Override
    public void run() {
       final Bitmap b = loadImageFromNetwork();
      myHandler.post(new Runnable() {                           

        @Override
        public void run() {
           mImageView.setImageBitmap(b);
          }
        });
      }
    })).start();                
}

enter image description here

Для получения дополнительной информации

http://android-developers.blogspot.com/2009/05/painless-threading.html

http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/

Ответ 2

Это делается на onCreate или onCreateView? Если это так, приложение может не находиться в состоянии, когда вид прикреплен к окну. Многие алгоритмы, основанные на показателях View, могут не работать, поскольку такие вещи, как измерения и позиция просмотра, возможно, не были рассчитаны. Андроидные анимации обычно требуют, чтобы они выполняли математику UI

View.post фактически ставит очередь анимации в цикле просмотра "Просмотр", поэтому, как только представление будет привязано к окну, оно выполняет анимацию вместо того, чтобы выполнить ее вручную.

Фактически вы выполняете действия в потоке пользовательского интерфейса, но в другое время

Ответ 3

Посмотрите здесь за хороший ответ. view.post() - это то же самое, что и handler.post(). Он переходит в очередь основных потоков и запускается после завершения остальных ожидающих задач. Если вы вызываете activity.runOnUiThread(), он будет вызываться немедленно в потоке пользовательского интерфейса.

Ответ 4

Проблема, я думаю, может быть методом жизненного цикла, когда вы вызываете метод post(). Вы делаете это в onCreate()? если да, посмотрите, что я нашел в документации onResume():

onResume()

Добавлен в API level 1 void onResume() Вызывается после onRestoreInstanceState (Bundle), onRestart() или onPause(), для вашего чтобы начать взаимодействие с пользователем. Это хорошее место для начать анимацию, открыть устройства с эксклюзивным доступом (например, камера) и т.д.

https://developer.android.com/reference/android/app/Activity.html#onResume()

Итак, как сказал Джо Плант, возможно, представление не готово начать анимацию в тот момент, когда вы вызываете post(), поэтому попробуйте переместить его в onResume().

PD: На самом деле, если вы переместите код в onResume(), тогда я думаю, что вы можете удалить вызов post(), поскольку вы уже находитесь в ui-потоке, и представление должно быть готово для начала анимации.