android 没有一个可以将所有应用程序数据统一放置的地方,即两个应用程序间的数据不能共享。但ContentProvider与ContentResolver可以解决多应用程序数据共享。
方法:
Demo1与Demo2:
1. Demo1 继承 ContentProvider类,实现里面的方法,主要包括:onCreate(),增删改查四个方法
代码:
public class MyContentProvider extends ContentProvider {
/**
*初始化时首先调用的方法
**/
@Override
public boolean onCreate() {
return false;
}
/**
* 查询方法,对应参数:访问此ContentProvider的uri;所查询的列名,如果填null,则返回表中所有的数据;where语句;where语句的参数;排序
**/
@Override
public Cursor query(Uri uri, String[] columns, String selection, String[] selectionArgs, String orderBy) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
return 0;
}
}
需要在AndroidManifest中注册此ContentProvider: <provider android:name=".MyContentProvider" android:authorities="com.hui.demo" />
注: android:authorities="com.hui.demo" 这段代码是指定此ContentProvider的authorities,类似于activity中的IntentFilter中action的作用,说白了就是这个ContentProvider在一个android系统中的名字。ContentProvider在这个应用程序启动以后,就会永远存在android系统中,直到卸载这个应用程序。
2. 新建一个Sqlite数据库
public class MySqlite extends SQLiteOpenHelper {
public static final String DB_NAME = "user_db";
public static final int DB_VERSION = 1;
public MySqlite(Context context){
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String sql = "create table user(" +
"id INTEGER PRIMARY KEY," +
"name varchar(100)" +
")";
sqLiteDatabase.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
3. 在第一步中的MyContentProvider类中增加操作MySqlite数据库的代码,其实非常简单,就操作SQLiteDatabase类中的增删改查方法。
代码:
public class MyContentProvider extends ContentProvider {
MySqlite mySqlite;
SQLiteDatabase sqLiteDatabase;
@Override
public boolean onCreate() {
mySqlite = new MySqlite(getContext());
sqLiteDatabase = mySqlite.getWritableDatabase();
return true;
}
@Override
public Cursor query(Uri uri, String[] columns, String selection, String[] selectionArgs, String orderBy) {
return sqLiteDatabase.query("user", columns, selection, selectionArgs, null, null, orderBy);
//由于SQLiteDatabase的查询方法中多两个参数,是groupBy和having是分组的意思,用不到可以写为null即不分组。
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
sqLiteDatabase.insert("user", null, contentValues);
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
sqLiteDatabase.delete("user", selection, selectionArgs);
return 0;
}
@Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
sqLiteDatabase.update("user", contentValues, selection, selectionArgs);
return 0;
}
}
这样Demo1 中 ContentProvider就完成了。可以在MySqilte表中加入几条数据用于测试。
4. 在Demo2中 :得到ContentResolver类然后根据指定的uri和表名,操作Demo1中的ContentProvider。从而达到两个应用程序间数据共享的目的。
代码:
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.parse("content://com.hui.demo/user");
//这里说一下:content://com.hui.demo/user 1.content:// 我觉得是类似一个命令头一样的功能
2.com.hui.demo 步骤1中的MyContentProvider的在AndroidManifest中注册时
android:authorities=""属性。找到指定ContentProvider的作用
3.user 表名
// 其实uri后面还可以有一项,比如说content://com.hui.demo/user/12 意思就是user表中id=12的记录。当然也可以在各个方法中selection和selectioArgs
// 即where语句中限制
//剩下就是非常简单的操作 contentResolver的增删改查的方法了。就列出简单的代码:
// Cursor cursor = contentResolver.query(uri, null, null, null, null);
// while (cursor.moveToNext()) {
// int id = cursor.getInt(cursor.getColumnIndex("id"));
// String name = cursor.getString(cursor.getColumnIndex("name"));
// Log.e("demo4", "id is :" + id + ", name is;" + name);
// }
// contentResolver.insert()
// contentResolver.update()
// contentResolver.delete()
UriMatcher
这里还有一个比较重要的类 UriMatcher类,此类的作用在于匹配访问 同一个ContentProvider 而不同表名的请求分发。假如Demo1中MySqilte类中数据库中初始化了两张不同的表,而Demo2又想分别操作这两张表,在Demo2中可以通过uri加入表名区分,而Demo1中在增删改查方法中uri字段还得取最后一块即表名用于区分来操作哪张表,非常麻烦。此时UriMatcher就派上了用场。
代码如下:
public class MyContentProvider extends ContentProvider {
static UriMatcher uriMatcher;
//用静态块初始化UriMatcher
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.hui.demo", "user", 1);
//参数意思: android:authorities="" 、表名、 唯一标识
uriMatcher.addURI("com.hui.demo", "student", 2);
}
@Override
public Cursor query(Uri uri, String[] columns, String selections, String[] argsSelections, String orderBy) {
switch (uriMatcher.match(uri)){ //通过此UriMatcher.match(Uri uri)方法通过得到唯一标识,就知道要操作哪张表了。
case 1:
//This is user table
break;
case 2:
//This is student table
break;
}
}
}