Android Loader 加载器

介绍:
Android 3.0引入加载器,支持在Activity 以及Fragment中异步加载数据。

可用于每个Activity 以及Fragment
支持异步加载数据
监控其数据并在内容变化时传递新的结果
在某一个配置更改后重建加载器时,会自动重新链接上一个加载器的Cursor,因此,他们无需重新查询其数据。

使用:

1 在Activity中可以调用getSupportLoaderManager()方法返回 LoaderManager的对象。

mLoaderManager = getSupportLoaderManager();
这里返回的是V4包下面的LoaderManager对象。

2 启动加载器。
mLoaderManager.initLoader(LOADER_ID, bundle, new MainPageLoaderCallBack());

initLoader() 方法采用以下参数:

int id 用于标识加载器的唯一 ID。在此示例中,ID 为 1。

Bundle args 在构建时提供给加载器的可选参数。

LoaderManager.LoaderCallbacks 实现, LoaderManager 将调用此实现来报告加载器事件。

initLoader() 调用确保加载器已初始化且处于Activity状态。这可能会出现两种结果:
如果 ID 指定的加载器已存在,则将重复使用上次创建的加载器。
如果 ID 指定的加载器不存在,则 initLoader() 将触发 LoaderManager.LoaderCallbacks 方法 onCreateLoader()。
在此方法中,我们可以实现代码以实例化并返回新加载器。之后我们会有实例展示如何使用。

initLoader()方法会返回Loader对象。LoaderManager 将自动管理加载器的生命周期。
LoaderManager 将根据需要启动和停止加载,并维护加载器的状态及其相关内容。这意味着我们很少需要与Loader的这个对象交互。

3 LoaderManager 还有一个方法为restartLoader(),即为重启Loader。
当存在含有制定Id的加载器,但你又想放弃之前的旧数据,重新开始执行,就可以电泳restartLoader()方法,参数和initLoader()方法一样。

4 LoaderManager.LoaderCallbacks 的几个回调方法:

onCreateLoader():针对指定的 ID 进行实例化并返回新的 Loader

一般我们会在这个方法中创建具体的Loader实例,用于做具体的逻辑。在下面我写的小Demo中在该方法中,创建了AsyncTaskLoader实例,用于异步加载数据。

onLoadFinished(Loader loader, D data) :将在先前创建的加载器完成加载时调用

当完成加载后,会执行这个方法,我们可以通过其传递回来的参数做我们想做的事情。因为整个Loader框架利用泛型,我们在实例化LoaderCallbacks时,所指定的类型,就是onLoadFinished
第二个参数返回的类型。

onLoaderReset(): 将在先前创建的加载器重置且其数据因此不可用时调用。

这个没什么好说的,目前我还没有用到过。

下面我们来看一个简单的实例:(这里没有用Google给的实例,我自己写了一个简单的实例,我觉得这个例子更能体现其使用的场景。)

public class MainActivity extends AppCompatActivity {

    private LoaderManager mLoaderManager;
    private static final String TAG = "main";
    private int LOADER_ID = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLoaderManager = getSupportLoaderManager();

        if(mLoaderManager.getLoader(LOADER_ID) == null) {
            mLoaderManager.initLoader(LOADER_ID, null, new MainPageLoaderCallBack(this)).forceLoad();
        }else {
            mLoaderManager.restartLoader(LOADER_ID, null, new MainPageLoaderCallBack(this)).forceLoad();
        }
    }

    public static class MainPageLoaderCallBack implements LoaderManager.LoaderCallbacks<String>{

        private Context context;
        public MainPageLoaderCallBack(Context context) {
            this.context = context;
        }

        @Override
        public Loader<String> onCreateLoader(int id, Bundle args) {
            return new MainPageLoader(context);
        }

        @Override
        public void onLoadFinished(Loader<String> loader, String data) {
            Log.d(TAG,"data : "+data);

        }

        @Override
        public void onLoaderReset(Loader<String> loader) {

        }
    }

    public static class MainPageLoader extends AsyncTaskLoader<String> {

        public MainPageLoader(Context context) {
            super(context);
        }

        @Override
        protected void onStartLoading() {
            super.onStartLoading();
        }

        @Override
        protected void onStopLoading() {
            super.onStopLoading();
        }

        @Override
        public String loadInBackground() {
            try{
                Thread.sleep(5000);
            }catch (Exception e){

            }

            return "load info";
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mLoaderManager != null) {
            mLoaderManager.destroyLoader(LOADER_ID);
        }
    }
}

其实上面的这个Demo,很好理解了,我相信你耐着心看到这里,一定能理解。哈哈。(在Demo中用的是V4包下面的加载器)
利用AsyncTaskLoader可以执行耗时的加载操作,甚至可以用来联网获取数据。

下面说一下在实际应用中,遇到的问题。
首先在上面的这个Demo中,除了loadInBackground()方法在子线程中,其他的回调方法都在主线程中。
在实际应用中遇到了这样的情况,调用了initLoader()方法启动加载器后,loadInBackground()方法不执行,
看Google给的Demo没有看到这样的说明,后来查找API无意间看到forceLoad()方法,调用之后,真个问题就解决了。

在利用其他Loader则不需要调用这个方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值