LoaderManager的使用,替代传统的ContentResolver查询。
最近在阅读google samples 的时候发现项目里查询联系人并不是按照我以前写的方式实现到,要是我写到话应该就是
getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);
然后在得到Cursor,再去遍历…
但是发现google developer使用到是一个CursorLoader和LoaderManager来实现到的,看了一下,代码比我以前写的这种方式更加清晰,简洁,然后就去看了一下官方介绍。
LoaderManager这个东西,在我们的activity和fragment中,都存在唯一的一个LoaderManager对象,我们可以通过getLoaderManager来获取这个对象。由LoaderManager来管理一个或多个Loader的启动、停止、保持、重启、关闭,这些都由LoaderManager来处理,通过LoaderCallbacks接口来监听Loader到变化。
Loader又是什么,它监听底层数据源,当数据发生改变时重新加载,activity切换的时候不会影响数据。它有一个子类是AsyncTaskLoader,当看到AsyncTask的时候就已经差不多明白了,这个类内部有一个AsyncTask来处理异步操作,而查询联系人用到的就是CursorLoader就是AsyncTaskLoader的子类,当然我们也可以自己继承它来根据自己的需求来自定义。
啊,,还是写代码来看一下怎样使用比较直观一点。
//实现LoaderCallbacks接口
public class LoaderTestFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_test,container,false);
//LoaderManager与当前的Loader关联进行查询操作
loadImages();
return rootView;
}
private void loadImages(){
getLoaderManager().restartLoader(0,null,this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//这里查询内存卡中的图片
return new CursorLoader(getActivity(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data != null){
//获取到数据到时候进行操作
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
//重置数据
}
}
主要就是
getLoaderManager().restartLoader(0,null,this);这个方法需要三个参数:
id是一个标识符,方便我们在调用destroyLoader的时候知道需要销毁哪个Loader。
args是可选的,就是在调用onCreateLoader()方法中到bundle,你可以根据传不同到参数来判断然后加载不同到数据
callback就是我们到LoaderCallback回调。
我们需要在实现LoaderCallback接口的时候指定数据的格式
然后在onLoadFinished()得到数据进行处理。
使用起来就是这么简单,而且还不用担心各种生命周期的麻烦,这些LoaderManager都会自己处理,而我们只需要关心回调函数中做我们的操作就ok了。