使用ContentProvider跨进程共享数据
来源:互联网 发布:买卖二代身份证 淘宝 编辑:程序博客网 时间:2024/06/14 14:01
欢迎Follow我的GitHub, 关注我的CSDN.
ContentProvider主要应用于进程间数据共享. 对于应用而言, 多进程并不会经常使用, 因而较少使用ContentProvider, 是最不常见的四大组件(Activity, Service, BroadcastReceiver, ContentProvider). 但是其优异的性能与便捷, 对于多应用共享数据而言, 非常重要, 比如共享同一份计步数据等. 开发者只有掌握多种技能, 才能在开发中游刃有余, 用最优的方式完成项目, 提升应用性能, 间接提高用户体验. 本文借用Demo, 讲解ContentProvider共享数据的要点.
本文源码的GitHub下载地址
SQLite
ContentProvider需要媒介进行数据存储, 最常用的就是SQLite数据库.
SQLite数据库继承SQLiteOpenHelper
类, 提供数据库名称, 表名, 版本. 在onCreate方法中, 创建数据库表, 添加字段.
本示例使用两张表, 书籍和用户.
public class DbOpenHelper extends SQLiteOpenHelper { private static final String DB_NAME = "book_provider.db"; public static final String BOOK_TABLE_NAME = "book"; public static final String USER_TABLE_NAME = "user"; private static final int DB_VERSION = 1; private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS " + BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY, name TEXT)"; private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY, name TEXT, sex INT)"; public DbOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK_TABLE); db.execSQL(CREATE_USER_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
直接使用数据库的情况较少, 也比较复杂, 推荐使用一些经典ORM数据库, 如Sugar等, 简化管理. ORM, 即对象关系映射.
ContentProvider
ContentProvider提供数据访问的接口, CRUD增删改查. 在onCreate中, 初始化数据库, 并添加数据.
@Override public boolean onCreate() { showLogs("onCreate 当前线程: " + Thread.currentThread().getName()); mContext = getContext(); initProviderData(); // 初始化Provider数据 return false;}private void initProviderData() { mDb = new DbOpenHelper(mContext).getWritableDatabase(); mDb.execSQL("delete from " + DbOpenHelper.BOOK_TABLE_NAME); mDb.execSQL("delete from " + DbOpenHelper.USER_TABLE_NAME); mDb.execSQL("insert into book values(3,'Android');"); mDb.execSQL("insert into book values(4, 'iOS');"); mDb.execSQL("insert into book values(5, 'HTML5');"); mDb.execSQL("insert into user values(1, 'Spike', 1);"); mDb.execSQL("insert into user values(2, 'Wang', 0);");}
CRUD的参数是Uri, 数据库需要使用表名, 为了便于从Uri映射到表名, 使用关系转换.
private String getTableName(Uri uri) { String tableName = null; switch (sUriMatcher.match(uri)) { case BOOK_URI_CODE: tableName = DbOpenHelper.BOOK_TABLE_NAME; break; case USER_URI_CODE: tableName = DbOpenHelper.USER_TABLE_NAME; break; default: break; } return tableName;}
添加数据insert
, 可以注册内容改变的监听, 插入数据时, 广播更新, 即notifyChange
.
@Nullable @Override public Uri insert(Uri uri, ContentValues values) { showLogs("insert"); String table = getTableName(uri); if (TextUtils.isEmpty(table)) { throw new IllegalArgumentException("Unsupported URI: " + uri); } mDb.insert(table, null, values); // 插入数据后通知改变 mContext.getContentResolver().notifyChange(uri, null); return null;}
删除数据delete
, 返回删除数据的数量, 大于0即删除成功.
@Override public int delete(Uri uri, String selection, String[] selectionArgs) { showLogs("delete"); String table = getTableName(uri); if (TextUtils.isEmpty(table)) { throw new IllegalArgumentException("Unsupported URI: " + uri); } int count = mDb.delete(table, selection, selectionArgs); if (count > 0) { mContext.getContentResolver().notifyChange(uri, null); } return count; // 返回删除的函数}
修改数据update
, 与删除类似, 返回修改数据的数量.
@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { showLogs("update"); String table = getTableName(uri); if (TextUtils.isEmpty(table)) { throw new IllegalArgumentException("Unsupported URI: " + uri); } int row = mDb.update(table, values, selection, selectionArgs); if (row > 0) { mContext.getContentResolver().notifyChange(uri, null); } return row; // 返回更新的行数}
查询数据query
, 返回数据库的游标, 处理数据.
@Nullable @Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { showLogs("query 当前线程: " + Thread.currentThread().getName()); String tableName = getTableName(uri); if (TextUtils.isEmpty(tableName)) { throw new IllegalArgumentException("Unsupported URI: " + uri); } return mDb.query(tableName, projection, selection, selectionArgs, null, null, sortOrder, null);}
注意Uri和表名的转换可能为空, 使用
TextUtils.isEmpty
判空.
共享数据
使用ContentProvider的独立进程, 模拟进程间共享数据.
<provider android:name=".BookProvider" android:authorities="org.wangchenlong.book.provider" android:permission="org.wangchenlong.BOOK_PROVIDER" android:process=":provider"/>
在AndroidManifest中, 把Provider注册在
:provider
进程中, 与主进程分离.
添加数据, 通过Uri找到ContentProvider, 使用ContentResolver
的insert
方法, 添加ContentValues
数据.
public void addBooks(View view) { Uri bookUri = BookProvider.BOOK_CONTENT_URI; ContentValues values = new ContentValues(); values.put("_id", 6); values.put("name", "信仰上帝"); getContentResolver().insert(bookUri, values);}
查询数据query
, 与数据库的使用方式类似, 解析出Cursor, 通过移动Cursor, 找到所有匹配的结果.
public void showBooks(View view) { String content = ""; Uri bookUri = BookProvider.BOOK_CONTENT_URI; Cursor bookCursor = getContentResolver().query(bookUri, new String[]{"_id", "name"}, null, null, null); if (bookCursor != null) { while (bookCursor.moveToNext()) { Book book = new Book(); book.bookId = bookCursor.getInt(0); book.bookName = bookCursor.getString(1); content += book.toString() + "\n"; Log.e(TAG, "query book: " + book.toString()); mTvShowBooks.setText(content); } bookCursor.close(); }}
效果
ContentProvider封装了跨进程共享的逻辑, 我们只需要Uri即可访问数据, 使用共享数据非常便捷, 需要掌握简单的使用方式.
OK, that’s all! Enjoy it!
- 使用ContentProvider跨进程共享数据
- ContentProvider跨进程共享数据
- Android跨进程数据共享——ContentProvider详解
- ContentProvider 跨进程数据读取
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 使用ContentProvider共享数据
- 存储网页为离线mht文件
- 存储网页为离线mht文件
- java面试题
- IT--linux--KVM--创建磁盘
- 全志H3平台CLOCK简析
- 使用ContentProvider跨进程共享数据
- Ubuntu14.04添加鼠标右键new_empty_file菜单
- 动态资源分配(Dynamic Resource Allocation)
- cocos2dx-实现CCDictionary的hash库uthash详解
- 记一次redis故障处理
- Polygon Collider 2D无法编辑的问题
- 设置文件资源管理器→我的电脑
- Windows设置文件资源管理器→我的电脑
- 单表 多表 树形表 一对多 springmvc spring mybatis SSM