前言
- 本文主要介绍使用ContentProvider + Sqlite + Loader等Android的基本组件实现高内聚低耦合的数据加载的数据设计模式,这是一种传统而高效的数据加载,熟悉这种模式同时也是对ContentProvider的更好掌握。
优势
ContentProvider可以非常简单的调整数据源而不影响其他程序。外部程序不关心数据,只关心返回的Cursor.举个例子,ContentProvider指向的数据库可以随时改变不会影响使用者,同时ContentProvider也可以返回网络数据,使用者只要求结果是Cursor,但是对于数据来自哪里并不关心,这样就实现了数据读取和使用的分离。
提供数据安全保护与权限管理,ContentProvider使用授权机制,对数据在方便访问的同时进行了很好地保护。
强大的API支持,Google官方提供了强大的API.
##Loader特点:
与Activity管理同步,与Activity/Fragment生命周期同步,创建与销毁都会受到Activity/Fragment生命周期的管理。这就意味着我们不需要再去考虑何时去加载数据,使用Loader之后会结合Activity或者Fragment的生命周期自行进行加载和更新。
内部线程异步加载,我们也就不需要再去开启线程获取数据解析数据,大大减少了代码量。
数据源发生改变时实时更新,貌似我们自己的数据数据是无法自动更新的,不过不要紧,只需要一行简单的reStartLoader就可以手动重新加载一下。
数据分层
- Loader 写操作
- ContentProvider
- SQLite
定义关系类
- 定义一个关系类,声明表结构,Uri,授权
1 | public class WebContract { |
继承ContentProvider
- 实现数据提供者,设定好Code作为表资源的唯一标示,使用UriMacher匹配
1 | public class WebContentProvider extends ContentProvider { |
使用Loader加载数据
```
adapter = new SimpleCursorAdapter(this,
R.layout.item_listview,
null,
new String[]{WebContract.History.Title, WebContract.History.Link},
new int[]{R.id.item_listview_title, R.id.item_listview_url},
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
listView.setAdapter(adapter);
getLoaderManager().initLoader(0x123, bundle, this);
//这是实现的
implements LoaderManager.LoaderCallbacks<Cursor> 的方法
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
int action = args.getInt("action");
CursorLoader cursorLoader = null;
Log.i("chendong", "action is " + action);
if (action == 0) {
//history
cursorLoader = new CursorLoader(this, WebContract.History.ContentUri, null, null, null, null);
} else {
cursorLoader = new CursorLoader(this, WebContract.BookMark.ContentUri, null, null, null, null);
}
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.i("chendong", "get data ");
adapter.changeCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
使用
getLoaderManager().restartLoader(0x123, bundle, this);
重新加载数据