设为首页收藏本站

移动叔叔

搜索
查看: 804|回复: 0
打印 上一主题 下一主题

[其它] Android中Loader实现ListView的异步加载

[复制链接]
跳转到指定楼层
楼主
发表于 2013-8-29 15:04:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 Android目前已经有了很多版本,现在就来了解下Android 3.0中的部分新的api。我们知道android 3.0 的sdk当中引入了很多新api,比如Loader。和Fragment类似(编写兼容android1.6的fragment),该api也可在android 1.6以上版本执行。
  :

  示例中有一个后台线程每隔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;
  }
  这里要注意,这个观察者模式是从sdk level 1就有的,也就是说,cursor可以接收通知来感知content provider数据变化,但是不能做到异步刷新界面。这次Loader机制通过官方支持实现了这个功能。
  另外,通过本示例也可观察到,当关闭Activity后,Content provider继续工作,它的后台线程还在不停的更新记录。
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 /1 下一条

© 2008-2024 移动叔叔. 版权所有,专业的网络售后平台 ( 闽ICP备18006692号-3 )

商务合作点击这里给我发消息|Email:service@mobileuncle.com|手机版|Archiver|移动叔叔     

GMT+8, 2024-4-25 20:21 , Processed in 0.145903 second(s), 12 queries , Gzip On, Memcache On.

返回顶部