使用传统Android组件实现高效数据加载
来源:互联网 发布:电脑双肩包 知乎 编辑:程序博客网 时间:2024/06/05 16:09
使用传统Android组件实现高效数据加载
本文主要介绍使用ContentProvider + Sqlite + Loader等Android的基本组件实现高内聚低耦合的数据加载的数据设计模式,这是一种传统而高效的数据加载,熟悉这种模式同时也是对ContentProvider的更好掌握。
优势:
1.ContentProvider可以非常简单的调整数据源而不影响其他程序。外部程序不关心数据,只关心返回的Cursor.举个例子,ContentProvider指向的数据库可以随时改变不会影响使用者,同时ContentProvider也可以返回网络数据,使用者只要求结果是Cursor,但是对于数据来自哪里并不关心,这样就实现了数据读取和使用的分离。
2.提供数据安全保护与权限管理,ContentProvider使用授权机制,对数据在方便访问的同时进行了很好地保护。
3.强大的API支持,Google官方提供了强大的API.
Loader特点:
1.与Activity管理同步,与Activity/Fragment生命周期同步,创建与销毁都会受到Activity/Fragment生命周期的管理。这就意味着我们不需要再去考虑何时去加载数据,使用Loader之后会结合Activity或者Fragment的生命周期自行进行加载和更新。
2.内部线程异步加载,我们也就不需要再去开启线程获取数据解析数据,大大减少了代码量。
3.数据源发生改变时实时更新,貌似我们自己的数据数据是无法自动更新的,不过不要紧,只需要一行简单的reStartLoader就可以手动重新加载一下。
数据分层:
Loader 写操作
ContentProvider
SQLite
下面就使用这种模式一步一步实现一下。
1.定义一个关系类,声明表结构,Uri,授权
public class WebContract { public static final String Tb_History = "tb_history"; public static final String Tb_BookMark = "tb_bookmark"; public static final String Authority = "com.march.db_browser"; public static class History implements BaseColumns { //content://com.march.db_browser/tb_history public static final Uri ContentUri = Uri.parse( "content://" + Authority).buildUpon().appendPath(Tb_History).build(); public static final String Link = "link"; public static final String Icon = "icon"; public static final String Title = "title"; public static final String Time = "time"; } public static class BookMark implements BaseColumns { //content://com.march.db_browser/tb_history public static final Uri ContentUri = Uri.parse( "content://" + Authority).buildUpon().appendPath(Tb_BookMark).build(); public static final String Link = "link"; public static final String Icon = "icon"; public static final String Title = "title"; public static final String Time = "time"; } }
2.继承ContentProvider实现数据提供者,设定好Code作为表资源的唯一标示,使用UriMacher匹配
public class WebContentProvider extends ContentProvider { /*为可以访问的数据库表资源定义代号,区分哪个表可以被访问*/ private static final int CODE_BOOKMARK = 0x1; private static final int CODE_HISTORY = 0x2; /*使用UriMacher生成访问的Uri*/ private static UriMatcher uriMatcher; /*使用静态代码块初始化UriMacher,添加*/ static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(WebContract.Authority, WebContract.Tb_BookMark, CODE_BOOKMARK); uriMatcher.addURI(WebContract.Authority, WebContract.Tb_History, CODE_HISTORY); } private MySqliteOpenHelper mySqliteOpenHelper; private SQLiteDatabase db; @Override public boolean onCreate() { mySqliteOpenHelper = new MySqliteOpenHelper(getContext(), "db_browser", 1); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = null; if (uri != null) { int code = uriMatcher.match(uri); db = mySqliteOpenHelper.getWritableDatabase(); switch (code) { case CODE_BOOKMARK: cursor = db.query(WebContract.Tb_BookMark, null, null, null, null, null, null); break; case CODE_HISTORY: cursor = db.query(WebContract.Tb_History, null, null, null, null, null, null); break; } } if (cursor == null) { Log.i("chendong", "cursor is null"); } // db.close(); //读操作不能关闭连接,写操作需要关闭连接 return cursor; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { Uri uri_return = null; if (uri != null) { int code = uriMatcher.match(uri); db = mySqliteOpenHelper.getWritableDatabase(); long id = -1; switch (code) { case CODE_BOOKMARK: id = db.insert(WebContract.Tb_BookMark, null, values); break; case CODE_HISTORY: id = db.insert(WebContract.Tb_History, null, values); break; } if (id != -1) { uri_return = ContentUris.withAppendedId(uri, id); } db.close(); } return uri_return; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // Implement this to handle requests to delete one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO: Implement this to handle requests to update one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } }
3.使用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); 重新加载数据
0 0
- 使用传统Android组件实现高效数据加载
- Android抛弃传统设计__使用角标实现分页加载
- App公共组件:加载数据Layout,高效开发必备!
- Android Gallery组件传统用法实现循环显示图像
- Android四大组件之使用ContentProvider实现数据共享
- 【Android】使用LoaderManager管理Loader实现异步动态加载数据
- Android使用原生组件WebView加载网页和数据的方法
- android 高效加载大图
- android高效加载图片
- android高效加载大图
- Android高效加载大图
- Android 高效加载图片
- Android高效加载Bitmap
- Android Bitmap高效加载
- android实现数据快速与组件交互
- 实现图片的高效加载
- Android高效加载大量图片
- Android 高效加载大图片
- 笔试题目整理
- [NOIP 2004]合唱队形 DP
- 第一篇文章
- linux的aix下的makefile参考
- Android之线程池的使用
- 使用传统Android组件实现高效数据加载
- [NOIP 2001]数的划分 DP
- Windows程序设计--文本输出(二)
- Decision Trees
- C++基础——C++风格的类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)
- 有关今后的学习计划
- Hadoop 元模式之作业归并
- iOS NSCondition结合代码以及项目进行详解
- [NOIP 2013]转圈游戏 快速幂