我想要实现的目标:
我有两个不同的片段。我希望他们两个以两种形式(在列表和地图上)显示相同的数据。我希望他们共享一个Loader(特别是AsyncTaskLoader
)。一切正常,但装载机不会重复使用。创建另一个并且数据加载两次。
我做了什么:
在Fragment
我使用LoaderManager lm = getActivity().getSupportLoaderManager();
在这两个中,我实现了LoaderCallbacks<ArrayList<Item>>
和所需的方法。
我使用lm.initLoader(0, args, this);
。
但是当我输出lm.toString()
时,看来这些是两个不同的装载机。数据下载两次。
如何从不同的活动/片段重新连接到同一个Loader?
这应该是可能的,因为无论如何,每个onCreate()
上下文都附加到Loader,例如关于配置改变。
答案 0 :(得分:5)
如何从与其启动的活动/片段不同的活动/片段重新连接到同一个Loader?
您不应重复使用Loader
个实例跨多个LoaderManager
和Activity
s管理的Fragment
。
LoaderManager
会针对Loader
/ Activity
生命周期启动/停止Fragment
个,因此无法保证那些Loader
Activity
一旦你进入另一个Loader
,它就会存在。
来自文档:
LoaderManager.LoaderCallbacks是一个让a的回调接口 客户端与LoaderManager交互。
加载器,特别是CursorLoader,应该保留它们的数据 被阻止后这允许应用程序保留其数据 跨越活动或片段的onStop()和onStart()方法,所以 当用户返回应用程序时,他们不必等待 要重新加载的数据。您使用LoaderManager.LoaderCallbacks方法 何时知道何时创建新的加载器,并告诉应用程序 什么时候停止使用加载器的数据。
换句话说,通常情况是您的Activity
将特定于某些活动(或片段)。当您LoaderManager.LoaderCallbacks
实施LoaderManager.LoaderCallbacks
界面后,您的活动将获得initLoader(int ID, Bundle args, LoaderCallbacks<D> callback)
类型。每次调用Loader
时,LoaderManager都会创建或重用LoaderManager.LoaderCallbacks
,该Activity
特定于Fragment
接口的某个实例(在本例中是您的Activity的实例)。这实质上是将Activity与一个Loader绑定在一起,并且当加载器状态发生变化时,将调用它的回调方法。
话虽如此,除非你能找到一种方法让你的两个独立的Activity共享相同的回调方法,我怀疑有一个干净的方法来做到这一点(即有一个Activity和一个Fragment共享相同的回调听起来像它即使不是不可能,也会很棘手)。我不会太担心它。在我见过的所有示例代码中,我从未见过两个Activity和/或Fragments共享相同的回调方法。此外,鉴于Loader
和{{1}}都应该被设计为重用,以这种方式共享{{1}}似乎不会被鼓励。
答案 1 :(得分:1)
是。它对我有用。我在导航抽屉中有3个不同的片段,其中相同的数据填充在不同的ListView中。 (所有碎片都是SAME活动的一部分)。
我的AsyncTaskLoader:
public class MyTaskLoader extends AsyncTaskLoader<HashMap<String, Integer>> {
public MyTaskLoader(Context context) {
super(context);
}
@Override
public HashMap<String, Integer> loadInBackground() {
...
return hashMap;
}
...
}
在所有碎片中使用相同的加载器ID。
片段1:
public class Fragment1 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {
//initialize adapter
getActivity().getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
// TODO Auto-generated method stub
return new MyTaskLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
HashMap<String, Integer> data) {
// TODO Auto-generated method stub
listAdapter.setData(data.keySet());
}
@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
// TODO Auto-generated method stub
listAdapter.setData(null);
}
}
对Fragment2使用相同的Id:
public class Fragment2 extends BaseFragment implements LoaderManager.LoaderCallbacks<HashMap<String, Integer>> {
@Override
public void onCreate(Bundle savedInstanceState) {
//initialize adapter
getActivity().getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<HashMap<String, Integer>> onCreateLoader(int arg0, Bundle arg1) {
// TODO Auto-generated method stub
return new MyTaskLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<HashMap<String, Integer>> arg0,
HashMap<String, Integer> data) {
// TODO Auto-generated method stub
listAdapter.setData(data.keySet());
}
@Override
public void onLoaderReset(Loader<HashMap<String, Integer>> arg0) {
// TODO Auto-generated method stub
listAdapter.setData(null);
}
}
在初始化加载程序之前,应初始化适配器。 到目前为止工作。 但是,这是正确的方法吗?是否有更好的方法为多个碎片使用通用加载器?
答案 2 :(得分:0)
我不太确定在完成讨论后你想要达到的目标。但是有一个application.registerActivityLifecycleCallbacks()
方法,它接受全局活动生命周期监听器(如onActivityCreated()
)。
答案 3 :(得分:0)
如果您在不同的片段和活动中使用相同的Loader ID,我认为您将拥有所需的行为。确保加载程序ID对要加载的数据是唯一的。例如,PhotosLoader和VideoLoader不应具有相同的ID。