Что является более эффективным широковещательным приемником или обработчиком?
Я знаю, что onReceive() приемника Broadcast и handleMessage() обработчика запускают один и тот же поток пользовательского интерфейса. Предположим, я хочу общаться между двумя службами в одном приложении (процессе). Я могу расширить класс вещательного приемника и зарегистрировать событие
ИЛИ
a Обработчик, а затем передайте свой экземпляр другой службе, которая будет использоваться для вызовов sendMessage(). В обоих случаях мне нужно будет добавить новый корпус коммутатора. Но какой подход более эффективен? Предположим, что код является потокобезопасным (без обновления пользовательского интерфейса).
Ответы
Ответ 1
Я могу расширить класс вещательного приемника и зарегистрировать событие
Если вы имеете в виду, что вы делаете это через LocalBroadcastManager
(см. г-н Капеллер отличный ответ для деталей), Handler
будет немного более эффективным, так как LocalBroadcastManager
используется Handler
. Однако разница в производительности не должна быть достаточной. То же самое можно сказать о других реализациях событий в технологическом процессе, таких как greenrobot EventBus и Square Otto. Все должно быть достаточно быстрым, чтобы другие проблемы, такие как ремонтопригодность, были первостепенными.
Если вы имеете в виду, что вы делаете это через системные трансляции (например, sendBroadcast()
, вызываемые в Context
), то Handler
, LocalBroadcastManager
или другие реализации шины событий будут значительно быстрее и более безопасными также.
Все это предполагает, что обе службы находятся в одном процессе.
Самое быстрое решение для всех - объединить две службы в одну. Это особенно верно, если они имеют одинаковую продолжительность жизни. Есть много случаев, когда наличие 2+ услуг в приложении разумно, но не создавайте множество независимых небольших сервисов без явной причины для этого.
Ответ 2
Вы не должны использовать обычные широковещательные передачи для связи между Activities
и Services
внутри вашего собственного приложения. Вместо этого вы должны использовать локальные трансляции! Сначала вы должны определить BroadcastReceiver
как для обычных передач:
private static final String ACTION_EXAMPLE = "ACTION_EXAMPLE";
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(ACTION_EXAMPLE.equals(intent.getAction())) {
...
}
}
};
После этого вы можете получить LocalBroadcastManager
следующим образом:
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
И вы можете зарегистрировать BroadcastReceiver
следующим образом (обычно вы регистрируете BroadcastReciever
в onResume()
):
@Override
public void onResume() {
super.onResume();
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
IntentFilter filter = new IntentFilter(ACTION_EXAMPLE);
manager.registerReceiver(this.receiver, filter);
}
Не забудьте отменить регистрацию BroadcastReceiver
позже (в onPause()
):
@Override
public void onPause() {
super.onPause();
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.unregisterReceiver(this.receiver);
}
И, наконец, вы можете отправлять локальные трансляции следующим образом:
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.sendBroadcast(intent);
Ответ 3
Широковещательные вызовы приемника - это тяжелые операции, и есть вероятность получить ANR, если событие транслируется несколько раз. А также контекст, который вы получаете в onReceive() широковещательного приемника, имеет ограниченное использование, пока не получите контекст приложения.
Напротив, вызовы обработчиков эффективны, поскольку они просты и работают в разных потоках, и для запуска вызова обработчика не требуется никакого контекста. связь между двумя службами или действиями или двумя потоками может быть легко обработана с помощью обработчика. Infact все другие способы, а именно: Intents и Связанные службы используют обработчики внутри для передачи сообщений.