AsyncTaskLoader的基本用法

使用AsyncTask加载数据时,如果遇到设备配置改变,或用户点击后退键等操作,
需要主动管理AsyncTask的生命周期,同时需要保存好下载数据。

此时,可以考虑使用AsyncTaskLoader,它继承自Loader(原生和支持库中均有实现)。
在遇到类似设备旋转等场景时,LoaderManager会帮我们妥善管理Loader及其加载的数据。
而且,LoaderManager还负责启动和停止loader,以及管理loader的生命周期。

当设备配置发生改变后,如果初始化一个已经加载完数据的loader,它能立即提交数据,
而不是再次尝试获取数据。


AsyncTaskLoader的基本用法如下所示,
主要包括创建回调接口、定义AysncTaskLoader的子类
及利用LoaderManager启动整个加载流程:

public class PhotoGalleryFragment extends Fragment{
    .............
    //指定Loader对应的id
    public static final int mLoaderId = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);

        //定义一个回调接口,一个callback可以监听多个loader
        //模板参数为AysncTaskLoader加载数据的返回值
        LoaderManager.LoaderCallbacks<List<GalleryItem>> callback =
                new LoaderManager.LoaderCallbacks<List<GalleryItem>>() {

            //LoaderManager创建Loader时,回调该接口
            @Override
            public Loader<List<GalleryItem>> onCreateLoader(int id, Bundle args) {
                //可以根据id创建出不同的Loader
                //要求创建出的loader,不能是非静态内部类
                //原因应该是避免内存泄露
                if (id == mLoaderId) {
                    Log.d("ZJTest", "onCreateLoader");
                    return new FetchItemsLoader(getActivity());
                } else {
                    return null;
                }
            }

            //FetchItemsLoader加载完数据时,就会回调该接口
            @Override
            public void onLoadFinished(Loader<List<GalleryItem>> loader, List<GalleryItem> data) {
                //同样可以根据id进行不同的操作
                if (loader.getId() == mLoaderId) {
                    Log.d("ZJTest", "onLoadFinished");

                    //可以进行更新界面等操作
                    mGalleryItems = data;
                    setupAdapter();
                }
            }

            @Override
            public void onLoaderReset(Loader<List<GalleryItem>> loader) {
            }
        };

        //利用LoaderManager启动Loader,指定loader对应的id、参数和回调接口
        getLoaderManager().restartLoader(mLoaderId, null, callback);
    }
    ...................
    //AsyncTaskLoader同样为抽象类,在模板参数中指定loadInBackground的返回值
    private static class FetchItemsLoader extends AsyncTaskLoader<List<GalleryItem>> {
        FetchItemsLoader(Context context) {
            super(context);
        }

        //必须实现这个方法,forceLoad为父类接口
        //调用该接口后,才会执行loadInBackground的操作
        @Override
        protected void onStartLoading() {
            Log.d("ZJTest", "onStartLoading");
            forceLoad();
        }

        //返回值将会传回给callback的onLoadFinished接口
        @Override
        public List<GalleryItem> loadInBackground() {
            Log.d("ZJTest", "loadInBackground");
            return new ImageFetcher().fetchItems();
        }
    }
 }

我们运行一下该段代码,log类似于:

02-14 15:41:01.080 11297-11297/stark.a.is.zhang.photogallery D/ZJTest: onCreateLoader
02-14 15:41:01.089 11297-11297/stark.a.is.zhang.photogallery D/ZJTest: onStartLoading
02-14 15:41:01.095 11297-11313/stark.a.is.zhang.photogallery D/ZJTest: loadInBackground
02-14 15:41:01.562 11297-11297/stark.a.is.zhang.photogallery D/ZJTest: onLoadFinished
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值