Подтвердить что ты не робот

Android: RunOnUiThread против AsyncTask

Я считаю, что 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
}

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

Edit:

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Хорошо провести время с кодированием в Android!

Ответ 4

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

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

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

Ответ 5

Это ОЧЕНЬ разные.

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

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

Edit:

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

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