I'm trying to achieve the following
- An Activity starts a background task (SyncAdapter) and shows a dialog.
- The background task sends broadcasts.
- These broadcasts should be intercepted by the dialog.
What I would expect is this:
Dialog Broadcast
<-------------------
OK!
<-------------------
OK!
....
<-------------------
OK!
But what I get is this:
Dialog Broadcast
<-------------------
<-------------------
....
<-------------------
(dialog dismiss)
OK!
OK!
....
OK!
As the diagram shows, the broadcasts are being sent correctly, but they are being received only after the dialog is dismissed. I want to receive them when the dialog is being shown. In other words, steps 1 and 2 are working fine, but 3. is working partially. What I think might be the problem is that I'm not using the proper context for the BroadcastReceiver.
So my question is: Which context should I use to subscribe for updates (i.e. receive the broadcasts, not send them), so that they can be picked up by the dialog when it is being shown?
I've tried with Activity.this
, Activity.this.getBaseContext()
and Activity.this.getApplicationContext()
, dialog.getContext()
, DialogFragment.getActivity()
to no avail.
Just to clarify: I've used the BroadcastReceiver pattern multiple times, I'm just having trouble when using it alongside a dialog.
FACTS:
- ACTIVITY (A) shows DIALOG (D)
- unknown type of (SOMETHING) named BACKGROUND TASK (T)
- (T) SENDS BROADCAST TO BROADCASTRECEIVER (R)
- (R) SHOULD DISMISS (D)
QUESTIONS:
- (T) do you mean CLASS DERIVED from AbstractThreadedSyncAdapter?
- do you somehow finish (A) after start of (T) and show (D)?
CONCLUSION:
- regardless what you do if your (A) create and shows (D) it is responsible to dismiss (D) & to do it before gets in onStop() state
- other words if activity will die without dismissed dialog you will get
android.view.WindowLeaked exception will be thrown.
- & when you try manipulate the dialog you will get:
java.lang.IllegalArgumentException: View not attached to window manager
The second part of your question, which concerns context
- you always can check which context is assigned to Dialog by method
Dialog.getContext()
- usen it to match other context
Dialog.getContext().equals(Context);
- also u can use Class method
Class.isAssignableFrom(Class<?> c)
- if u wanna match context to class (for example Activity u use)
MyActivity.class.isAssignableFrom(ObjectToMatch.getClass());
and I would forget to add:
you can always START DIALOG USING APPLICATION CONTEXT :)
& one more thing:
any stuff involving UI should by done on UI THREAD in case you will forgot & get
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
edit:
I DON'T SEE ANY PROBLEM : WORKING SOLUTION
This is a BroadcastReceiver
and you adapt it on your code. Instead of Activity.this
, Activity.this.getBaseContext()
and Activity.this.getApplicationContext()
you should use Context
like this :
class BroadCastReceiverTest extends BroadcastReceiver {
Context context;
public void onReceive(Context c, Intent intent) {
this.context = c;
}
Now you have to use this.context
as a Context
.
Try Otto
https://github.com/square/otto
From documentation,
An enhanced Guava-based event bus with emphasis on Android support.
Otto is an event bus designed to decouple different parts of your
application while still allowing them to communicate efficiently.
Forked from Guava, Otto adds unique functionality to an already
refined event bus as well as specializing it to the Android platform.