16

我想达到的目标:

我有两个不同的片段。我希望他们都以两种形式(列表和地图)显示相同的数据。我希望他们分享一个装载机(AsyncTaskLoader特别是)。一切正常,但装载程序没有被重复使用。创建另一个并加载数据两次。

我所做的:

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

但是当我输出时,lm.toString()它们似乎是两个不同的加载器。并且数据被下载了两次。

如何从不同于启动它的 Activity/Fragment 重新连接到同一个 Loader?

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

4

4 回答 4

5

如何从不同于启动它的 Activity/Fragment 重新连接到同一个 Loader?

不应该跨多个s 和s重复使用Loader由实例管理的s。LoaderManagerActivityFragment

将相对于/生命周期LoaderManager启动/停止那些s ,因此无法保证一旦您进入另一个 s 就会存在这些 s 。LoaderActivityFragmentLoaderActivity

从文档中:

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

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

换句话说,通常情况下,您Loader的 s 将特定于某个 Activity(或 Fragment)。当你Activity实现LoaderManager.LoaderCallbacks接口时,你的 Activity 被赋予 type LoaderManager.LoaderCallbacks。每次调用initLoader(int ID, Bundle args, LoaderCallbacks<D> callback)时,LoaderManager 都会创建或重用Loader特定于某个LoaderManager.LoaderCallbacks接口实例(在本例中是您的 Activity 实例)的 a。这本质上是把你的 Activity 和一个 Loader 绑定在一起,它的回调方法会随着 loader 状态的改变而被调用。

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

于 2012-04-07T18:24:09.843 回答
1

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

我的异步任务加载器:

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

应该在初始化加载器之前初始化适配器。工作至今。但是,这是正确的方法吗?有没有更好的方法来为多个片段使用通用加载器?

于 2015-01-06T05:42:41.190 回答
0

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

于 2013-04-14T08:13:22.587 回答
0

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

于 2016-08-31T19:56:18.167 回答