奇怪的AsyncTaskLoader行为

问题描述 投票:0回答:1

我的应用程序从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;
        }
    };
}
android asynctaskloader
1个回答
0
投票

根据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(用于观察“活动/片段”中的结果)的解决方案,编写的代码更少,而且更易于理解。

© www.soinside.com 2019 - 2024. All rights reserved.