我的应用程序从Internet下载JSON数据,并将其显示为RecyclerView列表。这是通过LoaderManager / Loader手段实现的。通过单击按钮来启动操作。
在onCreate中,如果该特定的加载程序已经存在,我将调用initLoader(),以便为其提供新的回调,并将其绑定到新的Activity(我这样做是为了确保用户在下载过程中旋转屏幕时不会失去进度) 。现在,我安排了在屏幕旋转时保留有组织的列表数据。例如,如果我加载数据然后旋转屏幕,则对initLoader()的调用将正确推断出已经加载了数据,并将调用onLoadFinished()(我怀疑加载的数据在某种程度上在内部进行了缓存)。
让我感到困惑的是,绝对会不必要地调用loadInBackground()。
阅读文档并没有为我澄清一些事情。
我如何仅在onCreate()上将新的回调传递给加载程序,而不调用不必要的操作?
编辑:这是AsyncTaskLoader代码。
@NonNull
@Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
@Override
protected void onStartLoading() {
Log.w("DBG", "onStartLoading");
if (args == null) return;
Log.w("DBG", "about to forceLoad");
forceLoad();
}
@Override
public String loadInBackground() {
Log.w("DBG", "loadInBackground");
String baseId = args.getString("baseId");
String quoteId = args.getString("quoteId");
String exchange = args.getString("exchange");
Uri uri = buildUri(baseId, quoteId, exchange);
String txt = uri.toString();
Log.i("Uri built: ", txt);
String response = "";
try {
URL url = new URL(uri.toString());
response = getResponseFromHttpUrl(url);
} catch (IOException e) {
e.printStackTrace();
}
final int PAUSE_SEC = 5;
try {
Thread.sleep(PAUSE_SEC * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return response;
}
};
}
根据Making loading data lifecycle aware blog post:
我们现在可以保留成员变量中的结果,并在配置更改后立即通过在我们的
deliverResult()
方法中调用onStartLoading()
立即返回它们。请注意,如果我们已经缓存了数据,那么如何不调用forceLoad()
-这是我们避免不断重载数据的方法!
仅检查您的参数是否为null是不够的,因为第二次调用initLoader()
通常会将相同的参数传递给Loader。相反,由AsyncTaskLoader来缓存结果并使用已经加载的数据的存在来明确地不从forceLoad()
调用onStartLoading()
。
请注意,根据同一篇博客文章:
[如果您正在寻找一种不依赖于加载程序的现代灵活解决方案(此处选择的解决方案,请查看Lifecycle Aware Data Loading with Architecture Components博客文章。
[您可能会发现基于ViewModel
(也可以保留配置更改的解决方案)和LiveData
(用于观察“活动/片段”中的结果)的解决方案,编写的代码更少,而且更易于理解。