web-dev-qa-db-ja.com

AndroidのBroadcastReceiversは新しいスレッドで開始されますか?

BroadcastReceiverクラス内でServiceを拡張する内部クラスがある場合、BroadcastReceiverクラスがServiceクラス?または別の言い方をすると、BroadacstReceiveronReceive()メソッドは追加のスレッドで開始されますか?

38
Flow

OnReceive()メソッドは、registerReceiver()バリアントを使用して別のスレッドでスケジュールするように要求しない限り、常にメインスレッド(「UIスレッド」とも呼ばれます)で呼び出されます。

Context.registerReceiver(BroadcastReceiver receiver,
                         IntentFilter filter,
                         String broadcastPermission,
                         Handler scheduler)
40
Nick Pelly

AndroidのBroadcastReceiversは新しいスレッドで開始されますか?

通常は必ずというわけではありませんが、すべて登録方法によって異なります。

BroadcastReceiverを登録する場合:

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

メインアクティビティスレッド(別名UIスレッド)で実行されます。

別のスレッドで実行されている有効なBroadcastReceiverを使用してHandlerを登録する場合:

registerReceiver (BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)

Handlerのコンテキストで実行されます

例えば:

HandlerThread handlerThread = new HandlerThread("ht");
handlerThread.start();
Looper looper = handlerThread.getLooper();
Handler handler = new Handler(looper);
context.registerReceiver(receiver, filter, null, handler); // Will not run on main thread

詳細 ここここ

21
Caner

onReceive()メソッドはメインスレッドで呼び出されます。 したがって、サービスクラスへのすべてのアクセスがメインスレッド内から行われる場合、同期は必要ありません。

18
Stephan

また、AndroidManifest.xmlで「Android:process」レシーバー要素属性を指定できます。 こちら を参照してください。これにより、レシーバーが別のプロセスとして実行され、メインのUIスレッドに関連付けられないように指定できます。

2
stoker

RegisterReceiver(broadcastReceiver, intentFilter).を使用すると、AndroidブロードキャストレシーバーはデフォルトでGUIスレッド(メインスレッド)で開始されます

ただし、次のようにワーカースレッドで実行できます。

HandlerThreadを使用する場合は、BroadcastReceiverの登録を解除した後、必ずスレッドを終了してください。そうでない場合、Linuxレベルでファイル記述子(FD)リークが発生し、登録/登録解除を続行すると、最終的にアプリケーションがクラッシュします。

unregisterReceiver(...);

次に、looper.quit();またはlooper.quitSafely();

private Handler broadcastReceiverHandler = null;
private HandlerThread broadcastReceiverThread = null;
private Looper broadcastReceiverThreadLooper = null;

private BroadcastReceiver broadcastReceiverReadScans = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

private void registerForIntents() {
    broadcastReceiverThread = new HandlerThread("THREAD_NAME");//Create a thread for BroadcastReceiver
    broadcastReceiverThread.start();

    broadcastReceiverThreadLooper = broadcastReceiverThread.getLooper();
    broadcastReceiverHandler = new Handler(broadcastReceiverThreadLooper);

    IntentFilter filterScanReads = new IntentFilter();
    filterScanReads.addAction("ACTION_SCAN_READ");
    filterScanReads.addCategory("CATEGORY_SCAN");

    context.registerReceiver(broadcastReceiverReadScans, filterScanReads, null, broadcastReceiverHandler);
}

private void unregisterIntents() {
    context.unregisterReceiver(broadcastReceiverReadScans);
    broadcastReceiverThreadLooper.quit();//Don't forget
}
0
Samantha