Android 3.0 sdk,引入了很多新api,比如Loader。和Fragment类似(编写兼容android1.6的fragment),该api也可在Android 1.6以上版本执行。

以下介绍如何编写Loader,实现对ListView的异步加载。效果如图:


示例中有一个后台线程每隔3秒更新数据库的长江记录,将记录改为“长江”或“Long River”。ListView无需监控数据库变化,基于Loader,会自动更新。实际上这里面是观察者模式,无非是系统自带了,只需调用即可,无需自己构造观察者。

这个示例也是完整的sqlite+content provider+cursor adapter+listview+loader组合示例。
编写前的准备类似编写兼容android1.6的fragment,需要导入jar包。 另外,2.3以前的Activity类没有提供一些Loader的帮助方法,需要让自己的Activity实现类继承FragmentActivity:
public class ListViewActivity extends FragmentActivity 

本示例是在在视图显示中使用Theme基础上实现的。
Activity类和RiverContentProvider类做了修改。
Activity类:

public class ListViewActivity extends FragmentActivity { private ListView riverListView; private SimpleCursorAdapter adapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initLoader(); setRiverListViewAdapter(); } private void initLoader() { getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Log.d("list", "on create loader"); CursorLoader cursorLoader=new CursorLoader(ListViewActivity.this, RiverContentProvider.CONTENT_URI, new String[] { RiverContentProvider._ID, RiverContentProvider.NAME, RiverContentProvider.INTRODUCTION }, null, null, null); //cursorLoader.setUpdateThrottle(1000); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { Log.d("list", "on loader finished"); adapter.swapCursor(cursor); } @Override public void onLoaderReset(Loader<Cursor> loader) { Log.d("list", "on loader reset"); adapter.swapCursor(null); } }); } private void setRiverListViewAdapter() { riverListView = (ListView) this.findViewById(R.id.riverList); Cursor cursor = managedQuery(RiverContentProvider.CONTENT_URI, null, null, null, null); adapter = new SimpleCursorAdapter(this, R.layout.row, cursor, new String[] { RiverContentProvider.NAME, RiverContentProvider.INTRODUCTION }, new int[] { R.id.riverName, R.id.riverIntroduction }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); riverListView.setAdapter(adapter); } 

主要是增加了initLoader方法。这里主要是实现了LoaderCallbacks接口。其中:

onCreateLoader,在创建activity时跟着onCreate会调用一次
onLoadFinished,每次改变和Loader相关的数据库记录后会调用一次
onLoaderReset,在关闭Activity时调用,释放资源

然后,在Content provider中,要调用类似观察者模式中通知的方法,即,在update方法中通知观察者记录改变,在query方法中注册观察者,这样通知来了可接收并处理。

update方法:

@Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int returnValue = database.update("rivers", values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return returnValue; } 

query方法:

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){ Cursor cursor = database.query("rivers", projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } 

更多相关文章

  1. Android(安卓)反编译apk 到java源码的方法
  2. Android完美解决输入框EditText隐藏密码打勾显示密码问题
  3. Android(安卓)官方示例:android-architecture 学习笔记(三)之todo
  4. 关于getting 'android:label' attribute: attribute is not a st
  5. Android(安卓)下拉刷新框架实现
  6. Android之RemoteViews篇下————RemoteViews的内部机制
  7. Android原生代码调用H5 Web网页中的Javascript函数方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. 图片背景平铺
  2. Android自定义控件按钮
  3. Android输入密码密文显示
  4. Android事件处理流程
  5. Android(安卓)Color.xml
  6. Android中的Shape属性
  7. Android(安卓)shape画圆点
  8. android intent action
  9. Android(安卓)label 倒是是怎么
  10. 常用颜色