BroadcastReceiver.onReceive her zaman UI iş parçacığında mı çalışır?


117

Uygulamamda, bir özel oluşturuyorum BroadcastReceiverve bunu manuel olarak Bağlamıma kaydediyorum Context.registerReceiver. Ayrıca AsyncTasknotifier-Intents'i aracılığıyla gönderen bir Context.sendBroadcast. Amaçlar, UI olmayan bir işçi iş parçacığından gönderilir, ancak BroadcastReceiver.onReceive(söz konusu Amaçları alan) her zaman UI iş parçacığında çalışır (bu benim için iyidir). Bu garantili mi yoksa buna güvenmemeli miyim?

Yanıtlar:


163

BroadcastReceiver.onReceive her zaman UI iş parçacığında mı çalışır?

Evet.


9
bu bir yerde belgelendi mi?
Hannes Struß

15
@hannes:% 99.44 oranında, Android kodunuzu çağırıyorsa, ana uygulama iş parçacığı üzerindedir. Tüm yaşam döngüsü yöntemleri (örneğin onCreate(), onReceive()) ana uygulama iş parçacığı üzerinde denir. Ve, onun için docs belgelenmiştir onReceive(): goo.gl/8kPuH
CommonsWare

2
Tamam, ben sadece dokümanlardaki "normalde ana iş parçacığı içinde çağrılır" ifadesini "her zaman" olarak yorumluyorum ve umarım işler bozulmaz ;-) Teşekkürler!
Hannes Struss

4
@Hannes Struß: Neden dillerini "normal" ile koruduklarını bilmiyorum. onReceive()Ana uygulama ("UI") iş parçacığı dışında bir iş parçacığında çağrılan herhangi bir durum düşünemiyorum .
CommonsWare

31
@CommonsWare: "onReceive () 'in ana uygulama (" UI ") iş parçacığı dışında bir iş parçacığında çağrıldığı herhangi bir durumu düşünemiyorum" - durum, BroadcastReceiver'ın registerReceiver (BroadcastReceiver, IntentFilter, String, İşleyici), işleyici bağımsız değişkeni boş değildir ve ana uygulama iş parçacığı dışındaki bir iş parçacığında oluşturulan bir işleyiciye başvurur.
Jules

76

Alıcıyı dinamik olarak kaydettiğiniz için, başka bir iş parçacığının (UI iş parçacığı dışında) onReceive(). Bu, registerReceiver () ' ın İşleyici parametresi aracılığıyla yapılır .

Bununla birlikte, başka bir İşleyici belirtmediyseniz, her zaman UI iş parçacığında işlenecektir.


Evet. İşleyici parametresi aracılığıyla bunu değiştirme yeteneğinize göre, dokümanlardaki dillerini "korumaya almışlar".
Andrew Mackenzie

64

BroadcastReceiver.onReceive her zaman UI iş parçacığında mı çalışır?

Genellikle, her şey onu nasıl kaydettiğinize bağlıdır.

BroadcastReceiverKullanarak kaydettirirseniz :

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

Ana etkinlik dizisinde (UI iş parçacığı olarak da bilinir) çalışacaktır .

Eğer senin kayıt varsa BroadcastReceiver, geçerli bir kullanarak Handler farklı bir iş parçacığı üzerinde çalışan :

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

Senin bağlamında çalışacak Handler

Örneğin:

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

Ayrıntılar burada ve burada .


3
Bu seçeneğe bir süre baktıktan sonra, sonunda LocalBroadcastManager'ın özel bir işleyici kullanmayı desteklemediğini fark ettim. Dolayısıyla, alıcınızı kaydetmek için bir bağlam yerine bir LBM kullanıyorsanız, bu yaklaşım geçerli değildir. Ne yazık ki, bu durumda, geriye kalan tek seçeneğimiz, arka plana geçmek ve alıcıların 10 saniye boyunca hareketsiz kaldıktan sonra tetiklediği ANR'lerden kaçınmak için bir Hizmet kullanmaktır.
gMale

9

Doğru şekilde belirtilen önceki yanıtlar , bir işleyiciyi kabul onReceiveederse, kayıtlı olduğu iş parçacığı üzerinde çalışacaktır registerReceiver()- aksi takdirde ana iş parçacığı üzerinde.

Alıcının kayıtlı olması LocalBroadcastManagerve yayın yoluyla olması dışında sendBroadcastSync- görünüşe göre arayan iş parçacığı üzerinde çalışacaktır.sendBroadcastSync.


Parçaya katılmıyorum and the broadcast is via sendBroadcastSync. Kullandığımız zaman LocalBroadcastManagerreciever kayıt, bu ana iş parçacığı olup olmadığını kullanımı ile çağrılması gerekir sendBroadcastSyncveya sendBroadcast. Yani anahtar, LocalBroadcastManagerkaydolmak için kullanmaktır . Haklı mıyım
kidoher

@kidoher: Buradaki kod bağlantılarını takip ettiniz mi: stackoverflow.com/q/20820244/281545 ?
Mr_and_Mrs_D

0

YES Context.registerReceiver (BroadcastReceiver alıcısı, IntentFilter filtresi, Dize yayın izni, İşleyici zamanlayıcı)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.