Si j'ai une classe intérieure qui s'étend BroadcastReceiver
dans ma catégorie Service
, devrais-je me soucier de la synchronisation, lorsque la classe BroadcastReceiver
lit lit/écrit aux objets du Service
classer? Ou de la mettre d'une autre manière: sont BroadacstReceiver
's onReceive()
méthodes ont commencé dans un fil supplémentaire?
La méthode Onreceive () est toujours appelée sur le thread principal (qui est également appelé "thread d'interface utilisateur"), à moins que vous ne le demandiez qu'il soit planifié sur un thread différent à l'aide de la variante RegisterRecefeiver ():
Context.registerReceiver(BroadcastReceiver receiver,
IntentFilter filter,
String broadcastPermission,
Handler scheduler)
Les radiodiqueurs de Android sont-ils lancés dans un nouveau fil?
Habituellement mais pas toujours, tout dépend de la façon dont vous l'enregistrez.
Si vous enregistrez votre BroadcastReceiver
utilisant:
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
Il fonctionnera dans le Fil d'activité principale (filetage de l'interface utilisateur).
Si vous enregistrez votre BroadcastReceiver
à l'aide d'un Handler
exécuté sur un autre fil:
registerReceiver (BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)
Il fonctionnera dans le contexte de votre Handler
Par exemple:
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
la méthode onreceive () est appelée sur le thread principal. Donc, au cas où tout votre accès à la classe de service est effectué à partir du fil principal, vous n'avez besoin de synchronisation.
De plus, vous pouvez spécifier l'attribut "Android: Process" Element d'élément de récepteur dans l'androidManifest.xml. Voir ICI . De cette façon, vous pouvez spécifier que le récepteur fonctionne comme un processus distinct et n'est pas attaché au fil principal de l'UI.
Les récepteurs de diffusion Android sont par défaut Démarrer dans le fil de l'interface graphique (fil principal) si vous utilisez RegisterReceiver(broadcastReceiver, intentFilter).
Mais il peut être exécuté dans un fil de travail comme suit;
Lorsque vous utilisez une poignée, assurez-vous de quitter le thread après la discrimination du BroadcastEver. Sinon, les fuites de descripteur de fichier (FD) se produisent sous du niveau Linux et enfin que l'application est écrasée si elle continue à enregistrer/désenregistrer.
unregisterReceiver (...);
Puis looper.quit (); Ou looper.Qui®Any ();
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
}