16

在LoaderManager中识别Loaders时,您使用唯一的ID。我在问这些ID有多独特。LoaderManager的范围是什么?

每个活动和片段是否都有自己的LoaderManager?片段是否使用它们所连接的Activity的LoaderManager?是否只有一个应用程序拥有的LoaderManager?

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

+3

[**了解LoaderManager(第2部分)**](http://www.androiddesignpatterns.com/2012/05/why-you-should-use-loadermanager.html) –

回答

8

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

一个简单的例子:

- DummyActivity延伸FragmentActivity/Log.d(Constants.LOGTAG “DummyActivity.onCreate” + getSupportLoaderManager()的toString()); (Data.Class)的数据类型为: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 arg和initLoader调用的onCreateLoader中的不同加载器)。

到目前为止,我设法 “重用” 一个Loader(...与否):

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

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

- 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上调用一个注册表。

待续...

+0

感谢您的回答!我一直在做一些iOS的东西,但应该有时间玩一下,并在一周左右完成回答这个问题。将回报! :) – num1

+0

因为我的同事们在等待,所以接下来的日子我也会继续努力。 – Renaud

+0

我最终会优化我的ContentProvider。对不起,不值得的奖励点...;) – Renaud

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

... 
} 

使用同一装载标识中的所有片段。

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

使用同一ID为Fragment2:

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

适配器应该初始化加载器之前被初始化。 迄今为止的作品。 但是,这是正确的方式吗?是否有更好的方法使用通用加载器来处理多个碎片?