首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的AsyncTaskLoader行为

奇怪的AsyncTaskLoader行为
EN

Stack Overflow用户
提问于 2019-11-29 06:14:09
回答 1查看 27关注 0票数 0

我的应用程序从互联网上下载JSON数据,并将其显示为RecyclerView列表。这是通过LoaderManager/Loader方法实现的。单击按钮即可启动操作。

在onCreate中,如果特定加载器已经存在,我会调用initLoader(),以便提供绑定到新活动的新回调(我这样做是为了确保用户在下载过程中旋转屏幕时不会丢失进度)。现在,我已经安排了在屏幕旋转时保留有组织的列表数据。例如,如果我加载数据,然后旋转屏幕,对initLoader()的调用将正确推断数据已经加载,并将调用onLoadFinished() (我怀疑加载的数据以某种方式在内部缓存)。

让我困惑的是,loadInBackground()也会以某种方式被调用,绝对是不必要的。

阅读文档对我来说并不是很清楚。

如何在不调用不必要的操作的情况下,仅在onCreate()上将新的回调传递给我的加载器?

编辑:这是AsyncTaskLoader代码。

代码语言:javascript
复制
@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;
        }
    };
}
EN

回答 1

Stack Overflow用户

发布于 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 (用于观察活动/片段中的结果)的解决方案一样,编写的代码要少得多,而且更容易理解。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59096704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档