Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 有关后台线程中数据更改的AsyncTaskLoader的正确通知_Android_Android Loader - Fatal编程技术网

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"));
        }
    }
    ...
}