LoaderManager的范围是什么?

时间:2011-09-06 20:20:21

标签: android android-fragments android-support-library android-loadermanager

在LoaderManager中识别装载程序时,使用唯一ID。我问的是这些ID有多独特。

每个活动和片段都有自己的LoaderManager吗?片段是否使用他们附加的Activity的LoaderManager?应用程序是否只拥有一个LoaderManager?

如果您可以告诉我如何更改您正在使用的LoaderManager,可以获得奖励积分。如果我希望我的Activity中的每个片段都使用相同的LoaderManager(其中一些是拉相同的数据并且共享Loaders会很好),那可能吗?

2 个答案:

答案 0 :(得分:8)

我目前正在将我的应用程序移植到android兼容包(主要用于CursorLoader和Fragments)。我目前正在尝试在两个片段之间共享一个CursorLoader,以便为我的ContentProvider提供查询。欢迎来到我的世界! ;)

一个简单的用例:

- DummyActivity扩展了FragmentActivity / Log.d(Constants.LOGTAG,“DummyActivity.onCreate”+ getSupportLoaderManager()。toString());

- DataFragment extends Fragment实现了LoaderManager.LoaderCallbacks / Log.d(Constants.LOGTAG,“DataFragment.onCreate”+ getLoaderManager()。toString());

- ReportFragment extends Fragment实现了LoaderManager.LoaderCallbacks / Log.d(Constants.LOGTAG,“ReportFragment.onCreate”+ getLoaderManager()。toString());

DummyActivity实例化DataFragment,后者实例化ReportFragment。 logcat输出显示每个LoaderManager的不同地址。作为第一个结论,每个片段似乎都有一个合适的LoaderManager ......

如果我能回答你的(我们的)问题,我会继续更新。如果您取得了任何进展,请分享您宝贵的知识。

<强>更新

我的假设是加载器ID仅与特定片段的LoaderManager的本地范围相关联,以使多个本地加载器与片段相关联(因此您可以基于id int返回onCreateLoader中的不同加载器) arg和initLoader调用)。

到目前为止,我设法“重用”了一个Loader(......或者不是):

- 首先,我在DummyActivity getSupportLoaderManager().enableDebugLogging(true);方法中使用onCreate启用了LoaderManager调试。

- 然后我从DataFragment和ReportFragment的getActivity().getSupportLoaderManager().initLoader(78, null, this);方法调用onCreate

- DataFragment通过mCursorLoader私有成员上的setter公开由onCreateLoader方法创建的CursorLoader。

- ReportFragment onCreateLoader返回DataFragment CursorLoader(在使用findFragmentByTag检索片段后)。

经过筛选(稍微混淆)的logcat输出:

      DummyApp  D  DummyActivity.onCreate
      DummyApp  D  DataFragment.newInstance
      DummyApp  D  ReportFragment.newInstance
      DummyApp  D  DataFragment.onCreate
 LoaderManager  V  initLoader in LoaderManager{405a19d0 in SpecificAction{4059ee98}}: args=null
      DummyApp  D  DataFragment.onCreateLoader
 LoaderManager  V    Created new loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
      DummyApp  D  DataFragment.onCreate
      DummyApp  D  DataFragment.onActivityCreated
      DummyApp  D  ReportFragment.onCreate
 LoaderManager  V  initLoader in LoaderManager{405a19d0 in DummyActivity{4059ee98}}: args=null
 LoaderManager  V    Re-using existing loader LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
      DummyApp  D  SpecificActionReportFragment.onCreate
      DummyApp  D  SpecificActionReportFragment.onActivityCreated
 LoaderManager  V  Starting in LoaderManager{405a19d0 in DummyActivity{4059ee98}}
 LoaderManager  V    Starting: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
 DummyProvider  D  query called
 DummyProvider  D  […]       
 DummyProvider  D  [end of query]
 LoaderManager  V  onLoadComplete: LoaderInfo{405a2298 #78 : CursorLoader{405a22e0}}
 LoaderManager  V    onLoadFinished in CursorLoader{405a22e0 id=78}: CursorWrapperInner{405afb20}
      DummyApp  D  ReportFragment.onLoadFinished
      DummyApp  D  ReportFragment.displayActionReport
      DummyApp  D  DummyActivity.setReportViewsVisibility
      DummyApp  D  ReportFragment.setSaveReportImageViewVisibility

这两个片段是从DummyActivity onCreate方法添加的(与描述的用例不同,但是对我们正在处理的问题没有任何改变)。不幸的是,加载器被重新分配到调用它的最新片段(这里是ReportFragment)......并且从不调用DataFragment.onLoadFinished。因此,ReportFragment看起来不错,但DataFragment不是最新的,因为从此类的onLoadFinished调用更新。

我假设有一个潜在的取消注册调用,然后是CursorLoader上的寄存器调用。

继续......

答案 1 :(得分:0)

是。它对我有用。我在导航抽屉中有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);
}
}

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