LoaderManager和Loader初步使用

Android 3.0中提供了一个新概念Loaders,这两天看了之前Contacts的源码,其中自己写了通话记录部分,发现源码里面有很多LoaderManager的使用,现在做一个总结,记录一下LoaderManager的基本用法:

这个其实是分为两部分:LoaderManager和自定义Loader,比如像加载联系人,短信这些系统提供ContentProvider的数据时,其实就是返回一个标准cursor,那我们就没必要自定义loader 直接用loaderManager来管理这个CursorLoader,这是一种简单普遍的情况。还有一种就是我们要加载非cursor类型的数据时,就必须自定义loader了。

1. LoaderManager和CursorLoader

举例用一个listFragment加载联系人,那么让它实现LoaderManager.LoaderCallbacks<Cursor> 接口,必须重写下面3个方法:

onCreateLoader: 这个是创建一个CursorLoader并返回,我们在里面new一个CursorLoader并返回就OK了

onLoadFinished: 这个是加载完成后更新UI,在这里就是setAdapter了 而这个加载过程其实就是在CursorLoader里面完成的,只不过系统帮我们完成了,而如果自定义loader的话就要自己完成,这就是区别!

onLoaderReset: loader的重置,在这里一般让UI不显示数据就行

就这么3个方法就可以完成数据加载了,核心就是把CursorLoader构造出来,至于加载过程,数据监听更新这些就有系统去完成吧!

<span style="font-size:14px;">public class ContactsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>{private SimpleCursorAdapter mAdapter; private final String[] CONTACTS_PROJECTION = new String[]{Contacts._ID,Co<span style="font-size:14px;">ntacts.DISPL</span>AY_NAME,Contacts.CONTACT_STATUS,Contacts.CONTACT_PRESENCE,Contacts.PHOTO_ID,Contacts.LOOKUP_KEY,};@Overridepublic void onActivityCreated(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onActivityCreated(savedInstanceState);setEmptyText("当前没有联系人");mAdapter = new SimpleCursorAdapter(getActivity(),android.R.layout.simple_list_item_2, null,new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },new int[] { android.R.id.text1, android.R.id.text2 }, 0);setListAdapter(mAdapter);getLoaderManager().initLoader(1, null, this);}@Overridepublic Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {// TODO Auto-generated method stubString select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("+ Contacts.DISPLAY_NAME + " != '' ))";return new CursorLoader(getActivity(), Contacts.CONTENT_URI, <span style="font-size:14px;"> </span>CONTACTS_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");}@Overridepublic void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {// TODO Auto-generated method stubmAdapter.swapCursor(arg1);}@Overridepublic void onLoaderReset(Loader<Cursor> arg0) {// TODO Auto-generated method stubmAdapter.swapCursor(null);}}</span>

2. 自定义Loader

但有些拿不到cursor这样的数据,我们就需要自定义Loader,其实在Loader里面只需要重写两个方法:一个onStartLoading,还有一个loadInBackground,但为了代码更加完善一些,再重写另外几个方法: onStopLoading onReset onCanceled,可以类比activity的生命周期,然后参考google文档进行重写,先贴出代码:

public class MySmsLoader extends AsyncTaskLoader<List<SmsEntry>> {private PackageManager mPm;private InstalledAppsObserver mAppsObserver;public MySmsLoader(Context context) {super(context);// TODO Auto-generated constructor stubmPm = getContext().getPackageManager();Log.d("dml", "new一个MySmsLoader");}@Overridepublic List<SmsEntry> loadInBackground() {Log.d("dml", "loadInBackground——–" );// TODO Auto-generated method stub // Retrieve all installed applications.List<ApplicationInfo> apps = mPm.getInstalledApplications(0);Log.d("dml", "apps >>>>>>>>>>" + apps);if (apps == null) {Log.d("dml", "apps null");apps = new ArrayList<ApplicationInfo>();}// Create corresponding array of entries and load their labels.List<SmsEntry> entries = new ArrayList<SmsEntry>(apps.size());for (int i = 0; i < apps.size(); i++) {SmsEntry entry = new SmsEntry();entry.setFrom_name(i+"::::::::");entry.setSend_time(apps.get(i).packageName);entries.add(entry);}Log.d("dml", "entries—->>>>>>>>>—-" + entries);return entries;}@Overrideprotected void onStartLoading() {// TODO Auto-generated method stubsuper.onStartLoading();if (mAppsObserver == null) {mAppsObserver = new InstalledAppsObserver(this);}forceLoad();}@Override protected void onStopLoading() {// The Loader has been put in a stopped state, so we should attempt to// cancel the current load (if there is one).cancelLoad();// Note that we leave the observer as is; Loaders in a stopped state// should still monitor the data source for changes so that the Loader// will know to force a new load if it is ever started again. }@Override protected void onReset() {// Ensure the loader is stopped.onStopLoading();// The Loader is being reset, so we should stop monitoring for changes.if (mAppsObserver != null) {getContext().unregisterReceiver(mAppsObserver);mAppsObserver = null;}}@Override public void onCanceled(List<SmsEntry> apps) {// Attempt to cancel the current asynchronous load.super.onCanceled(apps);// The load has been canceled, so we should release the resources// associated with 'mApps'.releaseResources(apps); } private void releaseResources(List<SmsEntry> apps) {// For a simple List, there is nothing to do. For something like a Cursor,// we would close it in this method. All resources associated with the// Loader should be released here.}}

onStartLoading:注册一些监听器到loader上,并且执行一次forceLoad(); 否则loader不会开始工作

我们一直在旅行,一直在等待某个人可以成为我们旅途的伴侣,

LoaderManager和Loader初步使用

相关文章:

你感兴趣的文章:

标签云: