全局加载器(LoaderManager),用于在多个活动/片段中重用

我想要实现的目标:

我有两个不同的片段。 我希望他们两个以两种forms(在列表和地图上)显示相同的数据。 我希望他们共享一个Loader(特别是AsyncTaskLoader )。 一切正常,但Loader不会被重复使用。 创建另一个并且数据加载两次。

我做的事:

Fragment我使用LoaderManager lm = getActivity().getSupportLoaderManager(); 在这两个中,我实现了LoaderCallbacks<ArrayList>和所需的方法。 在两者中我使用lm.initLoader(0, args, this);

但是当我输出lm.toString()它们似乎是两个不同的lm.toString() 。 数据下载两次。

如何从不同的活动/片段重新连接到同一个Loader,而不是从它开始的那个?

它应该是可能的,因为无论如何在每个onCreate()上都将上下文附加到Loader,例如在配置更改时。

如何从不同的活动/片段重新连接到同一个Loader,而不是从它开始的那个?

不应该在多个ActivityFragment重用由LoaderManager实例管理的Loader

LoaderManager将根据Activity / Fragment生命周期启动/停止那些Loader ,因此一旦你在另一个Activity ,就无法保证那些Loader会存在。

从文档:

LoaderManager.LoaderCallbacks是一个回调接口,允许客户端与LoaderManager进行交互。

加载器,特别是CursorLoader,在被停止后应该保留它们的数据。 这允许应用程序在活动或片段的onStop()和onStart()方法中保留其数据,这样当用户返回应用程序时,他们不必等待数据重新加载。 您可以使用LoaderManager.LoaderCallbacks方法知道何时创建新的加载器,并告诉应用程序何时停止使用加载器的数据。

换句话说,通常情况下,您的Loader将特定于某些Activity(或Fragment)。 当您的Activity实现LoaderManager.LoaderCallbacks接口时,您的Activity被赋予typesLoaderManager.LoaderCallbacks 。 每次调用initLoader(int ID, Bundle args, LoaderCallbacks callback) ,LoaderManager都会创建或重用一个特定于LoaderManager.LoaderCallbacks接口的某个实例的Loader (在本例中是一个Activity的实例) )。 这实际上将Activity与一个Loader绑定在一起,并且它的回调方法将在加载器状态发生变化时被调用。

话虽这么说,除非你能find一种方法让你的两个独立的Activity共享相同的回调方法,我怀疑有一个干净的方法来做到这一点(即有一个Activity和一个片段共享相同的回调听起来像是很棘手,如果不是不可能的话)。 我不会太担心它。 在我见过的所有示例代码中,我从未见过两个Activity和/或Fragments共享相同的回调方法。 此外,鉴于Activity s和Fragment都应该被设计为重用,以这种方式共享Loader似乎不会被鼓励。

是。 它对我有用。 我在导航抽屉中有3个不同的片段,其中相同的数据填充在不同的ListView中。 (所有碎片都是SAME活动的一部分)。

我的AsyncTaskLoader:

 public class MyTaskLoader extends AsyncTaskLoader> { public MyTaskLoader(Context context) { super(context); } @Override public HashMap loadInBackground() { ... return hashMap; } ... } 

在所有片段中使用相同的加载器ID。

片段1:

 public class Fragment1 extends BaseFragment implements LoaderManager.LoaderCallbacks> { @Override public void onCreate(Bundle savedInstanceState) { //initialize adapter getActivity().getSupportLoaderManager().initLoader(0, null, this); } @Override public Loader> onCreateLoader(int arg0, Bundle arg1) { // TODO Auto-generated method stub return new MyTaskLoader(getActivity()); } @Override public void onLoadFinished(Loader> arg0, HashMap data) { // TODO Auto-generated method stub listAdapter.setData(data.keySet()); } @Override public void onLoaderReset(Loader> arg0) { // TODO Auto-generated method stub listAdapter.setData(null); } } 

对Fragment2使用相同的Id:

 public class Fragment2 extends BaseFragment implements LoaderManager.LoaderCallbacks> { @Override public void onCreate(Bundle savedInstanceState) { //initialize adapter getActivity().getSupportLoaderManager().initLoader(0, null, this); } @Override public Loader> onCreateLoader(int arg0, Bundle arg1) { // TODO Auto-generated method stub return new MyTaskLoader(getActivity()); } @Override public void onLoadFinished(Loader> arg0, HashMap data) { // TODO Auto-generated method stub listAdapter.setData(data.keySet()); } @Override public void onLoaderReset(Loader> arg0) { // TODO Auto-generated method stub listAdapter.setData(null); } } 

应在初始化加载程序之前初始化适配器。 到目前为止工作。 但是,这是正确的方法吗? 是否有更好的方法为多个碎片使用通用加载器?

经过讨论后,我不太确定你想要的是什么。 但是有一个application.registerActivityLifecycleCallbacks()方法,它接受全局活动生命周期监听器(如onActivityCreated() )。

如果您在不同的碎片和活动中使用相同的Loader ID,我认为您将拥有所需的行为。 确保加载程序ID对要加载的数据是唯一的。 例如,PhotosLoader和VideoLoader不应具有相同的ID。