Loader简介以及CursorLoader的使用

Loader简介

Loader是一种封装特别好的异步加载资源的方式,我们可以通过继承AsyncTaskLoader或者Loader来实现我们的异步加载资源,也可以通过谷歌原生的子类来实现一些简单的异步资源加载,比如CursorLoader就比较适用于加载数据库,ContentProvider或者手机中的图片联系人等资源。

CursorLoader的使用

为了更好的体验Loader的强大,我们可以尝试一下使用CursorLoader,然后再深入学习一下
AsyncTaskLoader的使用以及实现机制。

通过将对应的 URI 以及其他的查询条件传递给CursorLoader及其子类,便可让其在后台高效地加载数据,等数据加载完成了便会返回一个 Cursor.,然后我们通过实现Loadermanager.LoaderCallbacks接口,在onLoadFinished(final Loader loader, final Cursor data)中取到我们需要的数据。

首先我们需要对CursorLoader继承,实现其子类,并且实现构造器,如下:

Public  class ChildOfCursorLoader extend CursorLoader {
public BoundCursorLoader( final Context context, final Uri uri,
        final String[] projection, final String selection, final String[] selectionArgs,
        final String sortOrder) {
    super(context, uri, projection, selection, selectionArgs, sortOrder);
  }
}

当然我们可以将其查询等条件设置为静态变量,如果是这样的话,我们可以看出一个子类只可以实现一种查询操作,在这种情况下我们可以使用单例模式,这样可以节省我们的内存空间,至于是懒汉还是饿汉,根据情况选择,同时要注意多线程模式下要保证安全。
当然最好还是不指定的方式更好一些,这样更加灵活,我们可以Loadermanager.LoaderCallbacks接口中的onCreateLoader()中定制自己的查询条件。

LoaderCallbacks

紧接着我们通过实现Loadermanager.LoaderCallbacks接口来加载数据。
先来了解一下这个接口的函数有哪些:
LoaderManager.LoaderCallbacks 接口包括以下方法:
onCreateLoader(int id,final Bundle args):针对指定的 ID 进行实例化并返回新的 Loader,当我们尝试访问加载器时(例如,通过LoaderManager. initLoader()),该方法将检查是否已存在由该 ID 指定的加载器。如果没有,它将触发 LoaderManager.LoaderCallbacks 中的 onCreateLoader() 方法。在此方法中,我们可以创建加载器,通过这个方法将返回 CursorLoader,但我们也可以实现自己的 Loader 子类。
onLoadFinished():将在先前创建的加载器完成加载时调用,当先前创建的加载器完成加载时,将会调用此方法。该方法必须在为此加载器提供的最后一个数据释放之前调用。此时,我们应该移除所有使用的旧数据(因为它们很快就会被释放),但不要自行释放这些数据,因为这些数据归加载器所有,加载器会处理它们。
onLoaderReset():当创建好的Loader被reset时调用此方法,会清空已绑定数据,此时CreatLoader会重新执行。

以下为实现接口的代码:

Public class myLoaderCallback implements Loadermanager.LoaderCallbacks<Cursor> {
	@overide
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
	    Uri baseUri;
	    if (mCurFilter != null) {
	        baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
	                  Uri.encode(mCurFilter));
	    } else {
	        baseUri = Contacts.CONTENT_URI;
	    }
	
	    String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
	            + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
	            + Contacts.DISPLAY_NAME + " != '' ))";
	    return new CursorLoader(getActivity(), baseUri,
	            CONTACTS_SUMMARY_PROJECTION, select, null,
	            Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
	}
	    
	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
		Mdata = data;
	}
	
	public void onLoaderReset(final Loader<Cursor> generic) {
		mlistener.onDataCursorUpdated(generic);
	}
}

通过上述代码我们可以看到,我们可以通过onCreateLoader()定制自己所需要的loader,从onLoadFinished中获取数据,最后在onLoaderReset()中获取更新后的Loader,然后对原本的数据进行处理。之后只需要两条代码就可以完成我们所需要的跟中查询。

LoaderManager mLoaderManager = getLoaderManager();
mLoaderManager.initLoader(LoaderId,null,callbacks);

值得注意的是getLoaderManager()这个方法通过activity或者Fragment的子类对象才可以调用。
这样我们就可以在callbacks.onLoadFinished(Loader loader, Cursor data)中获取数据,其参数data就是我们需要的数据。
如果对如何使用存在疑问的可以看一下这篇文章:
https://juejin.im/post/5a27c56e51882535cd4ab5af#heading-4

拓展

我们在使用Loader的时候,也可以结合工厂模式使用,就只需要在LoaderCallback通过一些简单的条件判断需要create哪种Loader,接下来两个方法也是如此。因为最近在学习代码,看过好几种使用方法,所以记录一下。

你可能感兴趣的:(Android)