是否始终需要从片段中的onCreate初始化initLoader?如果加载器的关键参数依赖于另一个加载器的结果怎么办?
即。你有2个加载器:LoaderA和LoaderB。 LoaderB需要LoaderA的结果才能运行。 LoaderA和LoaderB都在片段的onCreate中初始化,但LoaderB没有给出参数,因此它故意失败。 一旦LoaderA完成,LoaderB将使用新参数重新启动,以便它可以执行所需的请求。
片段中的加载器初始化:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_A, new Bundle(), this);
getLoaderManager().initLoader(LOADER_B, null, mLoaderBCallback);
}
在片段中回拨LOADER_A:
@Override
public Loader<MyResultObject> onCreateLoader(int id, Bundle args) {
return new LoaderA(getActivity(), args);
}
@Override
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) {
if (result != null) {
Bundle args = new Bundle();
args.putInt("id", result.getId());
getLoaderManager().restartLoader(LOADER_B, args, mLoaderBCallback);
}
}
片段中mLoaderBCallback的定义:
private LoaderBCallback mLoaderBCallback = new LoaderBCallback();
(LoaderBCallback的实现并不重要,它只是标准的LoaderCallbacks接口,它创建LoaderB的实例并在加载完成后进行处理。)
LoaderB类(请原谅这个类定义的任何潜在的编译器错误,它只是一个例子):
public class LoaderB<List<AnotherResultObject>> extends AsyncTaskLoader<List<AnotherResultObject>> {
private Bundle mArgs;
public LoaderB(Context context, Bundle args) {
super(context);
mArgs = args;
}
@Override
public List<AnotherResultObject> loadInBackground() {
if (mArgs == null) {
// bail out, no arguments.
return null;
}
// do network request with mArgs here
return MyStaticClass.performAwesomeNetworkRequest(mArgs);
}
// boiler plate AsyncTaskLoader stuff here
......
}
有更好的方法吗?我们可以不使用LoaderB的initLoader吗?
编辑:我的印象是加载器总是必须在onCreate中初始化,以便他们可以处理配置更改。这可能仅适用于活动中的装载者。在Fragments中创建的加载器是否被管理,无论它们在何处被初始化?
答案 0 :(得分:1)
您可以在代码中的任何位置初始化加载程序。
在您的情况下,您应该使用restartLoader
替换onLoadFinished中的initLoader
。只需从onActivityCreated for LOADER_B中删除initLoader
此外,您应该在onLoadFinished中检查加载程序的ID,以便知道哪个加载程序已完成。
编辑:你正在为LOADER_B
回调使用一个单独的监听器,所以我的ID检查点有点在那里被击败..但无论如何......你可以把它们组合成一个如果你想要
@Override
public void onLoadFinished(Loader<MyResultObject> loader, final MyResultObject result) {
switch (loader.getId())
{
case LOADER_A:
if (result != null) {
Bundle args = new Bundle();
args.putInt("id", result.getId());
// i put "this" as the callback listener. you can use your custom one here if you want
getLoaderManager().initLoader(LOADER_B, args, this);
}
break;
case LOADER_B:
//do whatever
break;
}