Android 有关后台线程中数据更改的AsyncTaskLoader的正确通知
我想为我的自定义数据源实现Android 有关后台线程中数据更改的AsyncTaskLoader的正确通知,android,android-loader,Android,Android Loader,我想为我的自定义数据源实现AsyncTaskLoader: public class DataSource { public interface DataSourceObserver { void onDataChanged(); } ... } DataSource将保留已注册观察员的列表,并将更改通知他们CustomLoader将实现DataSourceObserver。问题是如何正确地通知CustomLoader,因为必须从UI线程调用Loader
AsyncTaskLoader
:
public class DataSource {
public interface DataSourceObserver {
void onDataChanged();
}
...
}
DataSource
将保留已注册观察员的列表,并将更改通知他们CustomLoader
将实现DataSourceObserver
。问题是如何正确地通知CustomLoader
,因为必须从UI线程调用Loader.onContentChanged()
,但在我的情况下,DataSource
操作(以及调用DataSourceObserver.onDataChanged()
)将从后台线程完成
更新了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();
}
});
}
}
公共类CustomLoader扩展AsyncTaskLoader实现DataSource.DataSourceObserver{
私有最终处理程序observerHandler;
公共CustomLoader(上下文){
超级(上下文);
observerHandler=newhandler()
}
@凌驾
公共无效onDataChanged(){
post(新的Runnable(){
@凌驾
公开募捐{
onContentChanged();
}
});
}
}
我在使用本地广播的情况下取得了很多成功,这与您的情况非常相似。该方法涉及一个AsyncTaskLoader
实现,该实现将注册一个BroadcastReceiver
侦听描述所更改内容的特定字符串。此BroadcastReceiver
保留对加载程序的引用,并调用onContentChanged
。当数据需要刷新时,使用上述字符串进行本地广播,BroadcastReceiver
将听到并触发加载。下面是一些示例代码,如果您插入它,它可能无法完美工作,我已经概括了一些类名,但希望您能理解:
要在加载程序实现中使用的广播接收器:
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();
}
}
加载器实现在onStartLoading()中注册接收器
最后,以下是数据源中的onDataChanged将如何进行广播。它需要一个上下文来帮助发送广播。因为它可以从任意线程调用,所以我会使用ApplicationContext,因为如果活动被销毁,活动的上下文可能会导致问题
public class DataSource
{
public interface DataSourceObserver
{
void onDataChanged(Context applicationContext)
{
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("NEWDATASTRING"));
}
}
...
}
你可能会想玩一玩,看看它是如何为你工作的。您可以使用不同的字符串来区分需要加载的不同数据。您还需要在某个时候注销接收器,可能是在onReset()
中。如果评论中有任何不清楚的地方,请告诉我,我会尽力澄清。在CustomLoader构造函数中的ui线程fx上创建的处理程序如何(但请记住在ui线程上调用consyructor),然后使用Handler.post。。。无论如何,请尝试内容提供商。。。他们已经实现了。为了提示,我更新了我的问题。你觉得合适吗?我考虑过ContentProviders
,但对于我的应用程序来说,它们看起来太过分了,不需要外部访问数据。谢谢你的提示。看起来类似于事件总线模式。实际上它是有效的。考虑这个用例:我的屏幕将使用Web服务(IE.Load)每30秒刷新一次。OnCurrTunCudid()将每隔30秒调用一次。这不是Loader的有效用例吗?我已经在FakeServer类中包装了计时器任务,并通过广播received来完成这一任务。
public class DataSource
{
public interface DataSourceObserver
{
void onDataChanged(Context applicationContext)
{
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("NEWDATASTRING"));
}
}
...
}