contentprovider雖然是四大組件之一搏讶,但是實際開發(fā)中應(yīng)用實在是太少了,所以我經(jīng)常會忘記它的用法系吩,為了鞏固記憶方便回憶,寫一個簡單的demo來讓自己快速回憶contentprovider的用法穿挨。
本demo是contentprovider的跨進(jìn)程通信的用法,即創(chuàng)建了兩個工程帽衙,進(jìn)程一自定義了contentprovider贞绵,進(jìn)程二通過ContentResolver來訪問進(jìn)程一中的contentprovider的數(shù)據(jù)(對進(jìn)程一中自定義的contentprovider的數(shù)據(jù)庫進(jìn)行增刪改查操作)
進(jìn)程一:
先寫個數(shù)據(jù)庫的工具類用來創(chuàng)建數(shù)據(jù)庫(進(jìn)程二就是跨進(jìn)程操作此數(shù)據(jù)庫的)
public class DBHelper extends SQLiteOpenHelper {
// 數(shù)據(jù)庫名
private static final String DATABASE_NAME = "finch.db";
// 表名
public static final String USER_TABLE_NAME = "user";
public static final String JOB_TABLE_NAME = "job";
private static final int DATABASE_VERSION = 1;
//數(shù)據(jù)庫版本號
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 創(chuàng)建兩個表格:用戶表 和職業(yè)表
db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT)");
db.execSQL("CREATE TABLE IF NOT EXISTS " + JOB_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " job TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
再自定義一個自己的contentprovider榨崩。。DBHelper中有兩張表弹渔, UriMatcher是用來根據(jù)進(jìn)程二的ContentResolver調(diào)用的uri判斷進(jìn)程二到底是需要操作哪張表的數(shù)據(jù)的溯祸。
uri如下圖所示寫焦辅,AUTOHORITY是唯一的一般用包名來代替
這樣進(jìn)程二的ContentResolver才能根據(jù)uri(包含AUTOHORITY拼接出來的)找到對應(yīng)的contentprovider
記得在清單文件中也要寫上android:authorities="com.example.zhaoziliang"
public class MyProvider extends ContentProvider {
private Context mContext;
DBHelper mDbHelper = null;
SQLiteDatabase db = null;
public static final String AUTOHORITY = "com.example.zhaoziliang";
// 設(shè)置ContentProvider的唯一標(biāo)識
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);
// 初始化
mMatcher.addURI(AUTOHORITY,"user", User_Code);
mMatcher.addURI(AUTOHORITY, "job", Job_Code);
// 若URI資源路徑 = content://cn.scu.myprovider/user 筷登,則返回注冊碼User_Code
// 若URI資源路徑 = content://cn.scu.myprovider/job 哩盲,則返回注冊碼Job_Code
}
// 以下是ContentProvider的6個方法
/**
* 初始化ContentProvider
*/
@Override
public boolean onCreate() {
mContext = getContext();
// 在ContentProvider創(chuàng)建時對數(shù)據(jù)庫進(jìn)行初始化
// 運(yùn)行在主線程廉油,故不能做耗時操作,此處僅作展示
mDbHelper = new DBHelper(getContext());
db = mDbHelper.getWritableDatabase();
// 初始化兩個表的數(shù)據(jù)(先清空兩個表,再各加入一個記錄)
db.execSQL("delete from user");
db.execSQL("insert into user values(1,'Carson');");
db.execSQL("insert into user values(2,'Kobe');");
db.execSQL("delete from job");
db.execSQL("insert into job values(1,'Android');");
db.execSQL("insert into job values(2,'iOS');");
return true;
}
/**
* 添加數(shù)據(jù)
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
// 根據(jù)URI匹配 URI_CODE,從而匹配ContentProvider中相應(yīng)的表名
// 該方法在最下面
String table = getTableName(uri);
// 向該表添加數(shù)據(jù)
db.insert(table, null, values);
// 當(dāng)該URI的ContentProvider數(shù)據(jù)發(fā)生變化時班巩,通知外界(即訪問該ContentProvider數(shù)據(jù)的訪問者)
mContext.getContentResolver().notifyChange(uri, null);
// // 通過ContentUris類從URL中獲取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
return uri;
}
/**
* 查詢數(shù)據(jù)
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 根據(jù)URI匹配 URI_CODE抱慌,從而匹配ContentProvider中相應(yīng)的表名
// 該方法在最下面
String table = getTableName(uri);
// // 通過ContentUris類從URL中獲取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
// 查詢數(shù)據(jù)
return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
}
/**
* 更新數(shù)據(jù)
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// 由于不展示,此處不作展開
return 0;
}
/**
* 刪除數(shù)據(jù)
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 由于不展示,此處不作展開
return 0;
}
@Override
public String getType(Uri uri) {
// 由于不展示,此處不作展開
return null;
}
/**
* 根據(jù)URI匹配 URI_CODE抑进,從而匹配ContentProvider中相應(yīng)的表名
*/
private String getTableName(Uri uri){
String tableName = null;
switch (mMatcher.match(uri)) {
case User_Code:
tableName = DBHelper.USER_TABLE_NAME;
break;
case Job_Code:
tableName = DBHelper.JOB_TABLE_NAME;
break;
}
return tableName;
}
}
exported代表設(shè)置此provider是否可以被其他進(jìn)程使用
<provider
android:exported="true"
android:authorities="com.example.zhaoziliang"
android:name=".provider.MyProvider"/>
進(jìn)程二:
ContentResolver通過對應(yīng)匹配的uri去調(diào)用對應(yīng)的進(jìn)程一的contentprovider的不同的表進(jìn)行增刪改查操作
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 對user表進(jìn)行操作
*/
// 設(shè)置URI
Uri uri_user = Uri.parse("content://com.example.zhaoziliang/user");
// 插入表中數(shù)據(jù)
ContentValues values = new ContentValues();
values.put("_id", 4);
values.put("name", "zzl");
// 獲取ContentResolver
ContentResolver resolver = getContentResolver();
// 通過ContentResolver 根據(jù)URI 向ContentProvider中插入數(shù)據(jù)
resolver.insert(uri_user,values);
// 通過ContentResolver 向ContentProvider中查詢數(shù)據(jù)
Cursor cursor = resolver.query(uri_user, new String[]{"_id","name"}, null, null, null);
while (cursor.moveToNext()){
System.out.println("query book:" + cursor.getInt(0) +" "+ cursor.getString(1));
// 將表中數(shù)據(jù)全部輸出
}
cursor.close();
// 關(guān)閉游標(biāo)
/**
* 對job表進(jìn)行操作
*/
// 和上述類似,只是URI需要更改,從而匹配不同的URI CODE,從而找到不同的數(shù)據(jù)資源
Uri uri_job = Uri.parse("content://com.example.zhaoziliang/job");
// 插入表中數(shù)據(jù)
ContentValues values2 = new ContentValues();
values2.put("_id", 4);
values2.put("job", "LOL Player");
// 獲取ContentResolver
ContentResolver resolver2 = getContentResolver();
// 通過ContentResolver 根據(jù)URI 向ContentProvider中插入數(shù)據(jù)
resolver2.insert(uri_job,values2);
// 通過ContentResolver 向ContentProvider中查詢數(shù)據(jù)
Cursor cursor2 = resolver2.query(uri_job, new String[]{"_id","job"}, null, null, null);
while (cursor2.moveToNext()){
System.out.println("query job:" + cursor2.getInt(0) +" "+ cursor2.getString(1));
// 將表中數(shù)據(jù)全部輸出
}
cursor2.close();
// 關(guān)閉游標(biāo)
}
}