我想为我的自定义数据源实现 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 Implementation 在 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
}
最后,这里是 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/