android — Что именно делает метод post?" />

Что именно делает метод post?

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

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

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

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

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

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

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

86 голосов | спросил Gal 12 WedEurope/Moscow2012-12-12T16:39:43+04:00Europe/Moscow12bEurope/MoscowWed, 12 Dec 2012 16:39:43 +0400 2012, 16:39:43

4 ответа


0

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]

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

Тема пользовательского интерфейса:

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

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

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

  

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

Что произойдет, если пользователь нажмет кнопку, которая будет выполнять 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/

ответил Talha 12 WedEurope/Moscow2012-12-12T16:56:46+04:00Europe/Moscow12bEurope/MoscowWed, 12 Dec 2012 16:56:46 +0400 2012, 16:56:46
0

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

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

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

ответил Joe Plante 22 +04002014-10-22T19:54:46+04:00312014bEurope/MoscowWed, 22 Oct 2014 19:54:46 +0400 2014, 19:54:46
0

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

ответил Tas Morf 12 WedEurope/Moscow2012-12-12T16:47:45+04:00Europe/Moscow12bEurope/MoscowWed, 12 Dec 2012 16:47:45 +0400 2012, 16:47:45
0

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

  

onResume ()

     

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

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

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

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

ответил carrizo 15 22016vEurope/Moscow11bEurope/MoscowTue, 15 Nov 2016 09:09:00 +0300 2016, 09:09:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132