android - 适当通知 AsyncTaskLoader 有关后台线程的数据更改

标签 android android-loader

我想为我的自定义数据源实现 AsyncTaskLoader:

public class DataSource {
    public interface DataSourceObserver {
        void onDataChanged();
    }
    ...
}

DataSource 将保留已注册观察者的列表并通知他们有关更改。 CustomLoader 将实现 DataSourceObserver。问题是如何正确通知 CustomLoader,因为 Loader.onContentChanged() 必须从 UI 线程调用,但在我的例子中是 DataSource 操作(和调用到 DataSourceObserver.onDataChanged()) 将从后台线程完成。

根据 Selvin 提示的想法更新:

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();
            }
        });
    }
}

最佳答案

在与您的情况非常相似的情况下,我使用本地广播取得了很大的成功。该方法涉及一个 AsyncTaskLoader 实现,该实现将注册一个 BroadcastReceiver 监听描述更改内容的特定字符串。此 BroadcastReceiver 保留对 Loader 的引用并调用 onContentChanged。当数据需要刷新时,使用上述字符串进行本地广播,BroadcastReceiver 将听到它并触发加载。这是一些示例代码,如果将其放入其中可能无法完美运行,我已经概括了一些类名,但希望您能理解:

Broadcast Receiver 用于您的 Loader 实现:

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 ImplementationonStartLoading()

中注册 Receiver
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
}

最后,这里是 DataSource 中的 onDataChanged 将如何进行广播。它需要一个上下文来帮助发送广播。由于这可以从任意线程调用,我将使用您的 ApplicationContext,因为如果 Activity 被销毁,来自 Activity 的上下文可能会导致问题。

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

您可能想尝试一下,看看它是如何为您服务的。您可以使用不同的 String 来区分需要加载的不同数据。您还需要在某个时候注销 Receiver,可能是在 onReset() 中。如果评论中有任何不清楚的地方,请告诉我,我会尽力澄清。

关于android - 适当通知 AsyncTaskLoader 有关后台线程的数据更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18985067/

相关文章:

java - 我可以在不更改java代码的情况下在浏览器中打开webview链接吗?

android - Webview onDownloadStart 从未在 Android 5 或更高版本上调用

android - 如何使用 sqlite View 更新 Loader?

android - LoaderManager 的作用域是什么?

android - LoaderManager 与多个加载器 : how to get the right cursorloader

APP_ABI 的 Android NDK : what should I set in Application. mk?

android - 换行符和制表符未正确显示

java - 在 snackbar 操作中,如何确保从数据库中永久删除软删除记录是安全的?

android - 何时使用 Android 加载器

android - CursorLoader 连接到错误的 ContentProvider