Loader加载器的使用

特点以及作用:

  1. 作用类似于AsyncTask异步任务,在封装好的Loader使用过程中,提供一个现成的在子线程中执行的方法用于进行耗时操作,并且同时提供一个会在子线程结束后自动调用的方法用于更新UI页面
  2. 虽然Loader也能够读取网络数据,但是一般情况下,使用Loader多用于读取大量的数据库数据
  3. Loader中指定的加载任务会在页面经历onPause—onStop—onRestart—onStart—onResume时,Loader会在页面重新显示时自动重新加载数据(AsyncTask没有此作用).

一、通过Loader读取本地数据库中的内容(通过SQLiteOpenHelper创建的自产自销的数据库)

使用步骤:

1.初始化LoaderManager对象,稍后通过此对象启动加载任务

 //初始化LoaderManager对象
        manager = getLoaderManager();

2.调用initLoader方法启动加载任务

/*
         * 启动加载任务
         * 1. 给本次启动的异步任务分配一个唯一的id标识
         * 2. Bundle对象,用于携带数据以及传值,从主线程向Loader加载任务中传递数据
         * 作用类似于:异步任务中可以通过execute方法的参数向子线程中传入要连接的网址
         * 3. LoaderCallbacks的接口对象,用于提供一些Loader运行过程中的特殊时刻的回调方法 
         */
        manager.initLoader(1, null, this);

3.让当前类实现LoaderCallbacks接口,并实现接口中的抽象方法

//当创建Loader对象时调用
    //参数中的id和args就是调用initLoader方法时传递的参数一和参数二
    //返回值是一个Loader类型的加载任务对象,该对象用于封装具体要进行哪种耗时的加载任务
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // TODO Auto-generated method stub
        Log.i(TAG, "--------onCreateLoader  "+Thread.currentThread().getName());
        return new MyLoader(this);
    }
    //当加载任务执行完毕后调用的方法,参数2代表的就是加载结果
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // TODO Auto-generated method stub
        Log.i(TAG, "--------onLoadFinished");
        adapter.swapCursor(data);
//      当Loader配合SimpleCursorAdapter使用时,刷新适配器中的数据只需该边数据源即可
        //可省略notifyDataSetChanged的步骤
//      adapter.notifyDataSetChanged();
    }
    //当加载任务被重置时调用
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // TODO Auto-generated method stub
        Log.i(TAG, "--------onLoaderReset");

    }

4.创建一个AsyncTaskLoader的子类,并将子类对象作为onCreateLoader方法的返回值返回
5. 在AsyncTaskLoader的子类中手动添加onStartLoading方法,并在此方法中手动调用forceLoad方法
6. 在AsyncTaskLoader子类的loadInBackground方法中进行耗时操作,并将操作结果作为返回值返回

static class MyLoader extends AsyncTaskLoader<Cursor> {

        private Context context;
        public MyLoader(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            Log.i(TAG, "----- MyLoader  constractor");
            this.context = context;
        }

        //注意:不要忘记手动添加onStartLoadeing方法,并在此方法中调用forceLoad方法
        @Override
        protected void onStartLoading() {
            // TODO Auto-generated method stub
            super.onStartLoading();
            Log.i(TAG, "----- onStartLoading");
            //如果不调用此方法,下方法loadInBackground方法不会执行,
            forceLoad();
        }
        @Override
        public Cursor loadInBackground() {
            // TODO Auto-generated method stub
            Log.i(TAG, "----- loadInBackground "+Thread.currentThread().getName());
            return new MyHelper(context).getCursor();
        }
        //分发结果,在耗时操作执行结束后调用,在onLoadFinished方法运行后调用
        //参数代表当前的加载结果
        @Override
        public void deliverResult(Cursor data) {
            // TODO Auto-generated method stub
            super.deliverResult(data);
            Log.i(TAG, "----- deliverResult");
        }

    }

7.在LoaderCallbacks接口的实现方法onLoadFinished中根据加载结果进行更新UI的操作

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // TODO Auto-generated method stub
        Log.i(TAG, "--------onLoadFinished");
        adapter.swapCursor(data);
//      当Loader配合SimpleCursorAdapter使用时,刷新适配器中的数据只需该边数据源即可
        //可省略notifyDataSetChanged的步骤
//      adapter.notifyDataSetChanged();
    }

通过initLoader方法启动加载任务后程序的运行流程:

1.运行onCreateLoader方法,并判断该方法的返回值是否为null,如果为null,执行结束,不为null,继续向下执行
2.运行onCreateLoader方法返回值对象(Loader子类对象)的构造方法
3.运行onCreateLoader方法返回值对象(Loader子类对象)的onStartLoadeing方法
并判断该方法中是否调用了forceLoad方法,如果没有调用,在停止
如果有调用,则继续向下执行
4.运行loadInBackground方法,该方法中的代码运行在子线程中,可在此方法中进行耗时操作的处理
5.运行onLoadFinished方法
6.看onCreateLoader方法返回值对象(Loader子类对象)中是否重写了deliverResult方法,如果写了,则运行此方法

当需要重新启动加载任务时:

//启动加载任务重新查询数据
                // 参数与initLoader方法的参数作用相同
                Bundle args = new Bundle();
                args.putString("str", newText);
                manager.restartLoader(1, args, TwoActivity.this);
                return false;

二、通过Loader实现连网操作

三、通过Loader读取通过ContentProvider开放出来的数据

扫描二维码关注公众号,回复: 8700534 查看本文章
发布了34 篇原创文章 · 获赞 3 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/The_king_of_Asia/article/details/54880880