In my App, I create a custom BroadcastReceiver
and register it to my Context manually via Context.registerReceiver
. I also have an AsyncTask
that dispatches notifier-Intents via Context.sendBroadcast
. The intents are sent from a non-UI worker thread, but it seems that BroadcastReceiver.onReceive
(which receives said Intents) always runs in the UI thread (which is good for me). Is this guaranteed or should I not rely on that?
Does BroadcastReceiver.onReceive always run in the UI thread?
Yes.
onCreate()
, onReceive()
) are called on the main application thread. And, it is documented in the docs for onReceive()
: goo.gl/8kPuH –
Austronesian onReceive()
is called on a thread other than the main application ("UI") thread. –
Austronesian onReceive()
method. Will the thread break after onReceive()
method returns? –
Streusel registerReceiver()
) it is not safe for it to fork a thread. Android may terminate the process at any point after onReceive()
ends, particularly if there are no other components running. –
Austronesian registerReceiver()
?. As I have some blocking code in broadcast receiver and it may be take 1 or 2 secs so I am using a thread in the broadcast receiver so little worried about this. Between I am registering a broadcast receiver using IntentFilter at runtime. –
Streusel registerReceiver()
, the component that called registerReceiver()
is really the one that "owns" the thread and is responsible for its cleanup. –
Austronesian goAsync()
is a bit lacking in specifics, and so I prefer to use other means, such as delegating the work to a service. –
Austronesian registerReceiver()
on. If you use the versions of registerReceiver()
that take a Handler
, the thread associated with that Handler
(e.g., a HandlerThread
) will be used for calling onReceive()
of your receiver. Otherwise, it will be the main application thread. –
Austronesian LocalBroadcastManager.getInstance(this).registerReceiver()
and sendBroadcastSync()
, then onReceive()
runs on the thread of the broadcast sender. In my app's case that means it is sometimes the main thread and sometimes a background thread. –
Lasley onReceive()
of your receiver will be called on the main application thread, just like onCreate()
and other lifecycle events of Activity
and Service
. "can I still receive the broadcast?" -- onReceive()
will not be called. "If I can't, why? " -- because you are tying up the main application thread, so none of those sorts of callbacks can be called (and the framework can't do other relevant work on that thread). –
Austronesian onReceive()
, as all of that usually is in Java or Kotlin. "Is it a while loop waiting for a message to come?" -- actually, yes (see Looper
). "A gigantic loop with broadcast checks each iteration and my program on it too somehow?" -- the main application thread pulls messages off of a queue and calls methods on your objects to let you do work related to those messages. If you tie up the main application thread, it can no longer do that. –
Austronesian Since you dynamically register the receiver you can specify that another thread (other than the UI thread) handles the onReceive()
. This is done through the Handler parameter of registerReceiver().
That said, if you did not do specify another Handler, it will get handled on UI thread always.
Does BroadcastReceiver.onReceive always run in the UI thread?
Usually, it all depends how you register it.
If you register your BroadcastReceiver
using:
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
It will run in the main activity thread(aka UI thread).
If you register your BroadcastReceiver
using a valid Handler
running on a different thread:
registerReceiver (BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)
It will run in the context of your Handler
For example:
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
As the previous answers correctly stated onReceive
will run on the thread it's registered with if the flavour of registerReceiver()
that accepts a handler is called - otherwise on the main thread.
Except if the receiver is registered with the LocalBroadcastManager
and the broadcast is via sendBroadcastSync
- where it will apparently run on the thread that calls sendBroadcastSync.
and the broadcast is via sendBroadcastSync
. When we use LocalBroadcastManager
to register the reciever, it must be called by main thread whether use sendBroadcastSync
or sendBroadcast
. So the key is that using LocalBroadcastManager
to register. Am I right? –
Seabury © 2022 - 2024 — McMap. All rights reserved.