首页 > 解决方案 > AsyncTaskLoader 不会离线缓存数据

问题描述

我创建了一个 AsyncTaskLoader 用于从 API 加载 JSON 数据。但是,我注意到如果我旋转设备的屏幕,它会再次尝试从 API 加载数据。

结果,如果我关闭 Internet 连接并旋转屏幕,加载程序将无法返回数据,因为 HTTP 请求失败。

// NewsLoader.java
public class NewsLoader extends AsyncTaskLoader<String> {
    private String url;

    public NewsLoader(@NonNull Context context, String url) {
        super(context);
        this.url = url.trim();
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    @Override
    public String loadInBackground() {
        if (url == null || url.isEmpty()) return null;
        return NetworkUtils.fetchNews(url);
    }
}

然后,

// NewsActivity.java

// Initialising the loader
LoaderManager.getInstance(this).initLoader(LOADER_ID, args, this);

// onCreateLoader method
public Loader<String> onCreateLoader(int id, @Nullable Bundle args) {
    // Process args and get url
    return new NewsLoader(this, url);
}

据我所知,这不是装载机的正常行为。知道有什么问题吗?

标签: javaandroidasynctaskloader

解决方案


我最终弄清楚了问题所在。数据必须手动缓存,在 DeliverResult() 中拦截加载的数据并将其保存在实例变量中以备后用。

这是更新的代码。

// NewsLoader.java
public class NewsLoader extends AsyncTaskLoader<String> {
    private String url;
    private String cachedData = null;

    public NewsLoader(@NonNull Context context, String url) {
        super(context);
        this.url = url.trim();
    }

    @Override
    protected void onStartLoading() {
        if (cachedData != null) deliverResult(cachedData);
        else forceLoad();
    }

    @Override
    public String loadInBackground() {
        if (url == null || url.isEmpty()) return null;
        return NetworkUtils.fetchNews(url);
    }

    @Override
    public void deliverResult(String data) {
        cachedData = data;
        super.deliverResult(data);
    }
}

推荐阅读