Proper notification of AsyncTaskLoader about data changes from background thread

微笑、不失礼 提交于 2019-12-03 15:47:47

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 a BroadcastReceiver listening for a particular String that describes what's changed. This BroadcastReceiver keeps a reference to the Loader and calls onContentChanged. When the data needs a refresh, make the Local Broadcast with the aforementioned String and the BroadcastReceiver 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:

public class LoaderBroadcastReceiver extends BroadcastReceiver
{
    private Loader loader;

    public LoaderBroadcastReceiver(Loader loader)
    {
        this.loader = loader;
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        loader.onContentChanged();
    } 
}

Loader Implementation registers the Receiver in onStartLoading()

private LoaderBroadcastReceiver loaderBroadcastReceiver = null;

@Override
protected void onStartLoading()
{
     //... some code here

    if(loaderBroadcastReceiver == null)
    {
        loaderBroadcastReceiver = new LoaderBroadcastReceiver(this);
        LocalBroadcastManager.getInstance(getContext()).registerReceiver(loaderBroadcastReceiver, new IntentFilter("NEWDATASTRING"));
    }

    //... some more code here
}

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.

public class DataSource 
{
    public interface DataSourceObserver 
    {
        void onDataChanged(Context applicationContext)
        {
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("NEWDATASTRING"));
        }
    }
    ...
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!