我的应用程序从互联网上下载JSON数据,并将其显示为RecyclerView列表。这是通过LoaderManager/Loader方法实现的。单击按钮即可启动操作。
在onCreate中,如果特定加载器已经存在,我会调用initLoader(),以便提供绑定到新活动的新回调(我这样做是为了确保用户在下载过程中旋转屏幕时不会丢失进度)。现在,我已经安排了在屏幕旋转时保留有组织的列表数据。例如,如果我加载数据,然后旋转屏幕,对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;
}
};
}发布于 2019-11-30 00:18:42
根据Making loading data lifecycle aware blog post
我们现在可以将结果保存在成员变量中,并通过在
onStartLoading()方法中立即调用deliverResult(),在配置更改后立即返回它们。注意,如果我们已经缓存了数据,我们是如何不调用forceLoad()的--这就是我们避免不断地重新加载数据的方法!
检查参数是否为空是不够的,因为第二次调用initLoader()通常会将相同的参数传递给Loader。相反,应该由您的AsyncTaskLoader来缓存结果,并使用已加载数据的存在来明确地不从onStartLoading()调用forceLoad()。
请注意,根据同一篇博客文章:
如果你正在寻找一个现代的、灵活的、不依赖于Loaders的解决方案(这里选择的解决方案),请查看Lifecycle Aware Data Loading with Architecture Components博客文章。
正如您可能会发现基于ViewModel (它也能在配置更改中幸存下来)和LiveData (用于观察活动/片段中的结果)的解决方案一样,编写的代码要少得多,而且更容易理解。
https://stackoverflow.com/questions/59096704
复制相似问题