I want to implement AsyncTaskLoader
for my custom data source:
public class DataSource {
public interface DataSourceObserver {
void onDataChanged();
}
...
}
DataSource
will keep list of registered observers and will notify them about changes. CustomLoader
will implement DataSourceObserver
. The question is how to properly notify CustomLoader
since Loader.onContentChanged()
must be called from UI thread but in my case DataSource
operations (and calls to DataSourceObserver.onDataChanged()
) will be done from background threads.
Updated with idea from Selvin tip:
public class CustomLoader extends AsyncTaskLoader<...> implements DataSource.DataSourceObserver {
private final Handler observerHandler;
public CustomLoader(Context context) {
super(context);
observerHandler = new Handler()
}
@Override
public void onDataChanged() {
observerHandler.post(new Runnable() {
@Override
public void run() {
onContentChanged();
}
});
}
}
I've had a lot of success using Local Broadcasts in a case that's very similar to yours. The method involves an
AsyncTaskLoader
implementation that will register aBroadcastReceiver
listening for a particular String that describes what's changed. ThisBroadcastReceiver
keeps a reference to theLoader
and callsonContentChanged
. When the data needs a refresh, make the Local Broadcast with the aforementioned String and theBroadcastReceiver
will hear it and trigger the load. Here's some example code, it may not work perfectly if you drop it in, I've generalized some class names, but hopefully you'll get the idea:Broadcast Receiver to be used in your Loader Implmentation:
Loader Implementation registers the Receiver in
onStartLoading()
Finally, here's how onDataChanged in DataSource will make the Broadcast. It'll need a Context to help send the Broadcast. Since this can be called from an arbitrary Thread, I'd use your ApplicationContext, since an Context from an Activity could cause problems if the Activity is destroyed.
You'll probably want to play with it a bit to see how it works for you. You can use different Strings to differentiate different data that needs loading. You'll also want to unregister the Receiver at some point, perhaps in
onReset()
. Let me know if any of this in unclear in the comments, I'll try my best to clarify.