Android ContentProvider进程内通信
本章节讲述使用ContentProvider实现进程内通信 数据来源是SQLite
1.AndroidManifest.xml配置文件
<provider
android:name=".provider.MyContentProvider"
android:authorities="com.wjn.mycontentprovider"
android:enabled="true"
android:exported="true">
</provider>
android:exported属性设置成true:可被其他应用使用;
android:exported属性设置成false:只能被自己所在的应用使用;
2.ContentProvider实现类
public class MyContentProvider extends ContentProvider {
private Context mContext;
private DBSQLiteOpenHelper mDbHelper = null;
private SQLiteDatabase db = null;
public static final String AUTOHORITY = "com.wjn.mycontentprovider";//设置ContentProvider的唯 一标识 AndroidManifest.xml配置
public static final int User_Code = 1;
public static final int Job_Code = 2;
// UriMatcher类使用:在ContentProvider 中注册URI
private static final UriMatcher mMatcher;
static{
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 初始化
// 若URI资源路径 = content://cn.scu.myprovider/user ,则返回***User_Code
mMatcher.addURI(AUTOHORITY,"mytable", User_Code);
// 若URI资源路径 = content://cn.scu.myprovider/job ,则返回***Job_Code
mMatcher.addURI(AUTOHORITY, "mytable", Job_Code);
}
/**
* delete方法 删除数据
* */
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
String table = getTableName(uri);
return db.delete(table,selection,selectionArgs);
}
/**
* getType方法 获取数据类型
* */
@Override
public String getType(Uri uri) {
// 由于不展示,此处不作展开
return null;
}
/**
* insert方法 插入数据
* */
@Override
public Uri insert(Uri uri, ContentValues values) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
String table = getTableName(uri);
// 向该表添加数据
db.insert(table, null, values);
// 当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
mContext.getContentResolver().notifyChange(uri, null);
return uri;
}
/**
* onCreate方法
* 在ContentProvider创建时对数据库进行初始化
* 运行在主线程
* */
@Override
public boolean onCreate() {
mContext = getContext();
mDbHelper = new DBSQLiteOpenHelper(getContext(),"cdsp.db",null,1);
db = mDbHelper.getWritableDatabase();
db.execSQL("delete from mytable");//删除表中所有信息 可以做别的操作
return true;
}
/**
* query方法 查询数据
* */
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
String table = getTableName(uri);
// 查询数据
return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
}
/**
* update方法 更新数据
* */
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
String table = getTableName(uri);
return db.update(table,values,selection,selectionArgs);
}
/**
* 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
*/
private String getTableName(Uri uri){
String tableName = null;
switch (mMatcher.match(uri)) {
case User_Code:
tableName = "mytable";
break;
case Job_Code:
tableName = "mytable";
break;
}
return tableName;
}
}
3.SQLiteOpenHelper实现类
public class DBSQLiteOpenHelper extends SQLiteOpenHelper{
/**
* 构造方法
* */
public DBSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
/**
* onCreate方法
* 首次使用软件时生成数据库表
* */
@Override
public void onCreate(SQLiteDatabase db) {
String sql="CREATE TABLE mytable( id INTEGER, name VARCHAR(10), describe TEXT)";
db.execSQL(sql);
}
/**
* onUpgrade方法
* 在数据库的版本发生变化时会被调用, 一般在软件升级时才需改变版本号
* */
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql="DROP TABLE IF EXISTS mytable";
db.execSQL(sql);
onCreate(db);
}
}
4.java代码调用
private Uri uri_user;
// 设置URI
uri_user = Uri.parse("content://com.wjn.mycontentprovider/mytable");
增
// 插入表中数据
ContentValues values = new ContentValues();
values.put("id", 1);
values.put("name", "詹姆斯");
values.put("describe", "大家好,我是詹姆斯!");
// 获取ContentResolverContentResolver resolver = getContentResolver();
// 通过ContentResolver 根据URI 向ContentProvider中插入数据resolver.insert(uri_user,values);
删
// 获取ContentResolver
ContentResolver resolver = getContentResolver();
resolver.delete(uri_user,"id=1",null);
改
// 获取ContentResolver
ContentResolver resolver = getContentResolver();
ContentValues values=new ContentValues();//类似于map
values.put("name","API修改");
values.put("describe","大家好,我修改成功了!");
resolver.update(uri_user,values,"id=1",null);
查
// 获取ContentResolver
ContentResolver resolver = getContentResolver();
// 通过ContentResolver 向ContentProvider中查询数据
Cursor cursor = resolver.query(uri_user, new String[]{"id","name","describe"}, null, null, null);
StringBuilder sbBuilder=new StringBuilder();
while (cursor.moveToNext()){
int id=cursor.getInt(cursor.getColumnIndex("id"));
sbBuilder.append("ID:"+id+"\n");
String name=cursor.getString(cursor.getColumnIndex("name"));
sbBuilder.append("姓名:"+name+"\n");
String describe=cursor.getString(cursor.getColumnIndex("describe"));
sbBuilder.append("描述:"+describe+"\n\n\n");
}
textView6.setText(sbBuilder.toString());
cursor.close();// 关闭游标
5.结果
5.1.“增”——>“查”
5.2.“改”——>“查”
5.3.“删”——>"查"
6.ContentProvider优点
6.1.安全
ContentProvider为应用间的数据交互提供了一个安全的环境:允许把自己的应用数据根据需求开放给 其他应用 进行 增、删、改、查,而不用担心因为直接开放数据库权限而带来的安全问题。
6.2.访问简单高效
对比于其他对外共享数据的方式,数据访问方式会因数据存储的方式而不同:
6.2.1.采用 文件方式 对外共享数据,需要进行文件操作读写数据。
6.2.2.采用 Sharedpreferences 共享数据,需要使用sharedpreferences API读写数据
6.2.3.而采用ContentProvider方式,其 解耦了 底层数据的存储方式,使得无论底层数据存储采用何种方式,外界对数据的访问方式都是统一的,这使得访问简单 & 高效 。
7.总结