Мне просто интересно, есть ли времена, когда я должен выбрать Executor
над HandlerThread
. Есть ли времена, когда один превосходит другого, или я должен просто придерживаться HandlerThread
? В моем случае я в настоящее время слушаю ServerSocket
для соединений и обрабатываю каждый запрос в отдельном потоке, созданном Executor
. Несмотря на то, что я привел конкретный пример, я действительно ищу случаи, когда один из них более уместен, чем другой. Тем не менее, я приветствую комментарии о моем дизайне.
HandlerThread vs Executor - Когда еще один подход к другому?
Ответ 1
Класс Executor более мощный и может использовать пул потоков, тогда как каждый обработчик ссылается на один поток. Исполнитель позволяет вам выполнять все запланированные задачи и отменить их, если хотите. Обработчик, с другой стороны, не будет отвечать на простые вопросы, например, сколько задач ждет или даст мне ссылку на все задачи ожидания. Я считаю, что одна из причин того, что Handler более ограничена, заключается в том, что Android дает вам доступ к основному обработчику, который он использует для пользовательского интерфейса, и вы действительно можете испортить ОС, если вы начали отменять задачи ОС.
В общем, если вам нужен пул потоков или много энергии, используйте Исполнитель. Если вам просто нужен хороший фоновый поток для запуска одной задачи за раз, используйте Handler. В качестве примера, когда я хочу запросить мою базу данных, я просто хочу, чтобы один запрос возникал одновременно, и я не хочу генерировать ANR, поэтому я использую обработчик, работающий в фоновом потоке, чтобы запускать мои запросы.
Я считаю, что ваш выбор исполнителя звучит правильно, так как вы хотите обрабатывать несколько входящих запросов одновременно, и обработчик может делать только одно за раз.
UPDATE: как создать обработчик, который работает в фоновом потоке:
В вашем конструкторе или onCreate напишите следующее, очевидно, что вы можете установить приоритет по своему усмотрению:
public class MyClass {
private Handler mBgHandler;
public MyClass() {
HandlerThread bgThread = new HandlerThread("My-Background-Handler");
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
}
}
ОБНОВЛЕНИЕ: не забудьте оставить() или quitSafely() ваш HandlerThread, когда вы закончите с ним, иначе он останется в ожидании навсегда
Ответ 2
Я не буду следовать образцу кода в ответе satur9nine по состоянию на 2011-Dec-22.
Thread.MIN_PRIOROTY сопоставляется с android.os.Process.THREAD_PRIORITY_LOWEST. Цитата:
Самый низкий доступный приоритет потока. Только для тех, кто действительно, действительно не хочет бегать, если что-то еще происходит.
Я бы хотя бы использовал android.os.Process.THREAD_PRIORITY_BACKGROUND, например:
HandlerThread bgThread = new HandlerThread("handler name");
Process.setThreadPriority(bgThread.getThreadId(), Process.THREAD_PRIORITY_BACKGROUND);
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());
Это присваивает приоритет фонового изображения Android по умолчанию для потока.
В настоящее время потоки приоритета Process.THREAD_PRIORITY_BACKGROUND и ниже разделяют искусственно ограниченное количество процессорного времени с помощью Linux-группы, см., например, здесь. Если фоновая задача не просто ждет ввода-вывода, но и выполняет реальные вычисления, я бы подумал об увеличении своего приоритета с помощью android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE, который (в настоящее время) перемещает его из фоновой группы, но по-прежнему не представляет угрозы для пользовательского интерфейса и в режиме реального времени.
Обновление:. Ответ Satur9nine был полностью изменен в 2013-янв-08, чтобы не установить самый низкий приоритет. Теперь у HandlerThread подразумевается приоритет android.os.Process.THREAD_PRIORITY_BACKGROUND. Это означает, что теперь он получает приоритет фоновой задачи по умолчанию, но он по-прежнему ограничен потреблением искусственного максимума в 10% времени процессора вместе со всеми другими фоновыми задачами, которые могут существовать. Если это нежелательно, используйте мой код выше, например. с
Process.setThreadPriority(bgThread.getThreadId(),
Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
чтобы снять фоновый поток из группы.