欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用LoaderManager管理Loader实现异步动态加载数据

程序员文章站 2024-02-11 11:41:22
...
  • Loader特性

    • 对于每个Activity或者Fragment都可用

    • 提供异步加载数据

    • 监视数据资源,当内容改变时重新更新

    • 当配置改变时,自动重新连接最新的cursor,故不需要重新查询数据

  • Loader相关类接口

    • LoaderManager

      对于每个activity或者fragment只存在一个与之相关的LoaderManager对象,该LoaderManager对象可以存在多个可供管理loader对象。

    • LoaderManager.LoaderCallbacks

      LoaderManager.LoaderCallbacks是个回调接口,用于客户端与LoaderManager的交互,loader对象就是在其接口的onCreateLoader()方法中得到,在使用时需要覆盖其方法。

    • CursorLoader

      CursorLoader是AsyncTaskLoader的子类,通过它可以查询ContentResolver并返回一个Cursor对象,并使用该cursor对象在后台线程执行查询操作,以不至于会阻塞主线程,从一个内容提供者去异步加载数据是CursorLoader对象最大用处。

  • 简单使用Loader

    • 得到LoaderManager对象

      //得到LoaderManager对象  
      LoaderManager manager = content.getLoaderManager();  
    • 初始化Loader

      在activity的onCreate()方法区或者在fragment的onActivityCreated()方法区中,需要初始化一个Loader对象(可能已经存在或者新创建),getLoaderManager().initLoader(0, null, this);调用initLoader()方法是确保Loader对象已经初始化且可用,然而存在下面2种情况

      • ID存在

        如果指定ID的Loader已经存在,将重新使用最新的Loader对象

      • ID不存在

        如果指定的ID不存在,通过initLoader()方法,将会触发LoaderManager.LoaderCallbacks的onCreateLoader()方法并返回一个新的Loader

      虽然通过initLoader()可以得到Loader对象,但是我们不需要捕获该对象,但LoaderManager对象可以自动管理Loader生命周期,因此不需要直接与Loader对象直接交互

    • 实现LoaderCallbacks

      以典型的CursorLoader为例,app允许数据在onStart() 和 onStop()函数中传递,当用户重新进入app,不必等待数据重新加载,LoaderManager.LoaderCallbacks包含下面3个重要函数

      • onCreateLoader()

        Instantiate and return a new Loader for the given ID.

        当LoaderManager调用initLoader()时, 首先检查指定的id是否存在,如果不存在才会触发该方法,通过该方法才能创建一个Loader。返回创建的CursorLoader对象,其中可以在创建对象时,指定查询的条件,并携带一个Cursor对象。

        CursorLoader接收 uri projection selection selectionArgs sortOrder 等参数信息

        // 返回一个new CursorLoader对象  
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {  
            Uri uri = Uri.parse("content://com.baidu.provider/music");  
            return new CursorLoader(MainActivity.this, uri, null, null, null,  
                    null);  
        }  
      • onLoadFinished()

        Called when a previously created loader has finished its load.

        可以完成对UI控件的更新,比如更新一个listView列表。一旦应用不再使用,将自动释放loader的数据,不需要使用close();

        // 完成对UI主界面的更新  
        public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {  
            if(cursor == null){  
                Toast.makeText(MainActivity.this, "失败", 1).show();  
                return;  
            }  
            //ui主界面更新相关操作  
        }  
      • onLoaderReset()

        Called when a previously created loader is being reset, thus making its data unavailable.

    • 重启Loader

      通过指定相同的Loader ID,使用LoaderManager的restartLoader()方法,消除旧数据,加载新数据,达到动态更新的目的!可参考,ListView数据动态更新。

      // 当检测到数据已经释放改变时,重启指定ID的loader  
      if(u != null){  
          MainActivity.this.getLoaderManager().restartLoader(0, null, myLoader);  
          Toast.makeText(MainActivity.this, "插入成功", 1).show();  
      }else{  
          Toast.makeText(MainActivity.this, "插入失败", 1).show();  
      } 
  • Loader向下兼容

    • 当前Activity继承FragmentActivity

    • 得到LoaderManager对象

      public void load(View view) {  
          LoaderManager manager = this.getSupportLoaderManager();//注意不同  
          manager.initLoader(0, null, myLoader);  
      }  
    • 其余操作均不变,只不过导包时需要导入Android.support.v4下的包