Android: RunOnUiThread против AsyncTask
Я считаю, Google предлагает разработчикам использовать AsyncTask. Тем не менее, я хотел бы знать, как это отличается от использования «нового streamа», а затем вызова «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();
против
- Недостаточная производительность Haskell foldl с (++)
- clflush для аннулирования строки кэша через функцию C
- Переходы CSS3: «Переход: все» медленнее, чем «переход: x»?
- Когда и почему базы данных объединяются дорого?
- Android onClick в XML против OnClickListener
AsyncTask:
onPreExecute() { // some code #1 } doInBackground() { // some code #2 } onPostExecute() { // some code #3 }
Каковы преимущества / недостатки?
Редактировать:
Я не ищу ответов, таких как «легче видеть код», «удобный для разработчиков» и т. Д. Я фактически ищу технические различия за сценой.
Например, ответ Пола Никоновича был бы ответом, который я хотел видеть. (Но AsyncTask ведет себя одинаково)
- Ошибка производительности XmlSerializer при указании XmlRootAttribute
- Не пытайтесь ли вы блокировать блокировки, если исключения не выбрасываются?
- MySQL: многие таблицы или многие базы данных?
- Как влияет динамическая переменная на производительность?
- Храните PostgreSQL от выбора плохого плана запроса
- Студия Android занимает слишком много памяти
- jQuery: первый против .first ()
- Заголовок Content-Length по сравнению с закодированным кодированием
Когда вы используете new Thread
stream, вы создаете новый stream каждый раз, когда выполняете это. Однако AsyncTask
использует статический пул максимум 128 streamов и будет использовать старый stream всякий раз, когда он существует. Таким образом, запуск AsyncTask 10 раз в серийном режиме будет создавать только один stream, который запускает задачу 10 раз вместо 10 streamов.
Это одно из различий среди многих.
Это, по сути, удобство. Структура AsyncTask
имеет дело с управлением пулом Thread
и обеспечивает простой, понятный интерфейс. Хорошо известно – тем, кто знает, как использовать AsyncTask
– что активность пользовательского интерфейса может продолжаться в onPreExecute()
, onPostExecute()
и onProgressUpdate()
, и что весь «тяжелый подъем» выполняется в doInBackground()
где вы не можете коснуться пользовательского интерфейса.
Это облегчает разработчику простую фоновую задачу, которая может легко публиковать обновления в streamе пользовательского интерфейса и возвращать результаты по завершении. Это не волшебство, это просто удобство.
В соответствии с этим AsyncTask
проще в использовании, но имеет некоторые ограничения, такие как:
- Исправлен размер пула ядра и рабочая очередь: 5 пулов / 10 элементов
- он жестко закодирован и не может быть изменен
- Приоритет streamа фиксируется на низком уровне
- Обработка исключений не так хорошо поддерживается, как в
Thread
Также будет другая разница, которую я не понял. Вы можете найти и проверить полный исходный код AsyncTask, поскольку Android является открытым исходным кодом 🙂
Хорошо провести время с кодированием в Android!
Основной недостаток заключается в том, что использование вашей собственной нити будет поддерживать вашу активность в жизни, когда будет вызвана фишка. Android предоставит вам время для всех ваших streamов. Это приводит к возникновению утечки активности, которая в конечном итоге заставит ваше приложение работать очень медленно до тех пор, пока ваше приложение не перестанет работать с пользователем или операционной системой.
Вы можете проверить это, посмотрев ваш процесс в АБР. Даже когда деятельность завершена, вы все равно увидите, что она висит там, занимая ресурсы.
Итак, если вы используете свой собственный stream, убедитесь, что вы его управляете. Или просто используйте андроид-апи. Выбор ваш.
Это ОЧЕНЬ разные.
- Первое взаимодействие с пользователем осуществляется на основном streamе, а также на всех графических функциях.
- Вторая
AsyncTask
предназначена для коротких всплесков выделенной активности, таких как загрузка файла или загрузка некоторых данных. - В-третьих, потому что все пользовательские интерфейсы и пользовательские взаимодействия выполняются в основном streamе, если вы начнете подталкивать материал к этому streamу, устройство будет отставать и меньше реагировать на команды пользователя.
Единственная причина, по которой вы хотите запустить что-то в streamе пользовательского интерфейса, – это взаимодействие с виджетами. Помимо этого, если вы хотите выполнять длительную обработку, используйте AsyncTask
.
Редактировать:
Вы можете загружать свои данные в отдельный stream, и у меня нет проблем с этим. Проблема возникает, когда вы хотите обновить интерфейс. В одиночку невозможно изменить пользовательский интерфейс из дочернего streamа. Вместо этого вам придется создать либо обработчик, связанный с streamом пользовательского интерфейса, либо создать новый stream, который предназначен для запуска в streamе пользовательского интерфейса (как в вашем примере). Это не только утомительно, но и трагическая трата ресурсов. AsyncTask
позаботится об этом просто и эффективно.
Чтобы ответить на ваш последний вопрос, вы правы. AsyncTask
имеет доступ к основному streamу в pre / postExecute. Тем не менее, обработка (основной источник задержки UI), которую эта задача выполняет, не является. С помощью Задачи пользовательский интерфейс будет влиять только на то, что вы рисуете, а не на то, чтобы ждать, пока задача завершит свою работу и что бы она ни рисовала.