Android: RunOnUiThread и AsyncTask - PullRequest
       1

Android: RunOnUiThread и AsyncTask

35 голосов
/ 15 февраля 2012

Я считаю, что Google предлагает разработчикам использовать AsyncTask.Однако я хотел бы знать, чем он отличается от использования «нового потока» и последующего вызова «RunOnUiThread» в плане производительности и эффективности использования памяти.

Пример использования RunOnUithread:

    // some code #1
    Thread t = new Thread("Thread1") {
        @Override
        public void run() {
            // some code #2
            runOnUiThread(new Runnable() {
                public void run() {
                    // some code #3 (that needs to be ran in UI thread)

                }
            });

        }
    };
    t.start();

против.

AsyncTask:

onPreExecute() {
   // some code #1
}

doInBackground() {
   // some code #2
}

onPostExecute() {
   // some code #3
}

Каковы преимущества / недостатки?

Редактировать:

Я не ищу такие ответы, как «легче увидеть»код »,« удобный для разработчиков »и т. д. Я на самом деле ищу технические различия за кулисами.

Например, ответ Пола Никоновича ниже был бы ответом, который я хотел бы увидеть.(Но AsyncTask ведет себя так же)

Ответы [ 5 ]

51 голосов
/ 16 февраля 2012

Когда вы используете new Thread, вы действительно создаете новый поток каждый раз, когда выполняете это. AsyncTask однако, использует статический пул максимум 128 потоков и будет использовать старый поток всякий раз, когда он существует. Таким образом, 10-кратный запуск AsyncTask создаст только один поток, который будет выполнять задачу 10 раз вместо 10 потоков.

Это одно из различий среди многих.

12 голосов
/ 15 февраля 2012

Это удобство, по сути.Инфраструктура AsyncTask имеет дело с управлением пулом Thread и предоставляет простой, понятный интерфейс.Те, кто знает, как использовать AsyncTask, хорошо знают, что действия пользовательского интерфейса могут продолжаться в onPreExecute(), onPostExecute() и onProgressUpdate(), и что вся "тяжелая работа" выполняется в doInBackground() там, где вы не можете прикоснуться к пользовательскому интерфейсу.

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

4 голосов
/ 15 июня 2012

Согласно это , AsyncTask проще в использовании, но имеет некоторые ограничения, такие как:

  • Размер основного пула и рабочая очередь фиксированы: 5 пулов /10 элементов
    • жестко запрограммированы и не могут быть изменены
  • Приоритет резьбы установлен на низкий
  • Обработка исключений не так хорошо поддерживается, как с Thread

Также будет еще одно отличие, которое я не понял.Вы можете найти и проверить полный исходный код AsyncTask , поскольку Android является открытым исходным кодом: -)

Приятного времяпровождения с кодированием в Android!

4 голосов
/ 15 февраля 2012

Основным недостатком является то, что использование собственного потока сохранит вашу активность, когда вызывается метод Finish.Android даст вам время активности для завершения всех ваших тем.Это приводит к возникновению утечки активности, которая в конечном итоге приведет к тому, что ваше приложение будет работать очень медленно, пока ваше приложение не будет принудительно завершено ни пользователем, ни ОС.

Вы можете убедиться в этом, посмотрев на ваш процесс в АБР.Даже когда действие закончено, вы все равно увидите, что оно висит там, занимая ресурсы.

Итак, если вы используете свой собственный поток, убедитесь, что вы управляете им.Или просто используйте Android-API.Выбор за вами.

1 голос
/ 15 февраля 2012

Это очень по-разному.

  • Первое ВСЕ пользовательское взаимодействие выполняется в основном потоке, а также во всех графических работах.
  • Второе AsyncTask предназначено для коротких всплесков выделенного действия, например загрузки файла.или загрузка некоторых данных.
  • В-третьих, поскольку все пользовательский интерфейс и взаимодействия с пользователем выполняются в главном потоке, если вы начнете помещать данные в этот поток, устройство будет зависать и меньше реагировать на команды пользователя.

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

Edit:

Вы можете загрузить свои данные в отдельном потоке, и у меня нет проблем с этим.Проблема возникает, когда вы хотите обновить пользовательский интерфейс.В одиночку невозможно изменить пользовательский интерфейс из дочернего потока.Вместо этого вам придется создать либо обработчик, связанный с потоком пользовательского интерфейса, либо создать новый поток, предназначенный для выполнения в потоке пользовательского интерфейса (как в вашем примере).Это не только утомительно, но и трагически трата ресурсов.AsyncTask позаботится об этом просто и эффективно.

Что касается вашего последнего пункта, вы правы.AsyncTask имеет доступ к основному потоку в pre / postExecute.Однако обработка (основной источник задержки пользовательского интерфейса), которую выполняет задание, не выполняется.При выполнении задания на пользовательский интерфейс будет влиять только то, что вы рисуете, в отличие от необходимости ждать, пока задание завершит свою работу, и любого рисунка, который он хочет сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...