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

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

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

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

Это начинается.

Я напечатал CurrentThread перед началом анимации и обоими main .

Очевидно, что у меня что-то отсутствует, так как оба должны начать анимацию в основном потоке … Мое предположение заключается в том, что, поскольку пост добавляет задачу в очередь, она начинается в более «правильное время», но мне бы очень хотелось знать Что здесь происходит на большей глубине.

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

Solutions Collecting From Web of "Что именно делает почтовый метод?"

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

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

Run () : Запускает выполнение активной части кода класса. Этот метод вызывается при запуске потока, который был создан с классом, который реализует Runnable.

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

Code : getView().startAnimation(a);

В вашем коде,

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

Поэтому startAnimation будет запущен в новом потоке, когда он будет получен из messageQueue

[РЕДАКТИРОВАТЬ 1]

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

Пользовательский интерфейс:

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

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

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

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

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

 ((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(); } 

укротитель

 final Handler myHandler = new Handler(); (new Thread(new Runnable() { @Override public void run() { final Bitmap b = loadImageFromNetwork(); myHandler.post(new Runnable() { @Override public void run() { mImageView.setImageBitmap(b); } }); } })).start(); } 

Введите описание изображения здесь

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

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

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

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

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

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

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

Проблема, я думаю, может быть методом жизненного цикла, когда вы вызываете метод 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-thread, и представление должно быть готово для запуска анимации.