- 工具:Android Studio,XMind桑包,馬克飛象绽昼,印象筆記
- 2016年12月8日,Google中國開發(fā)者大會在京舉行派草,同時正式上線了Google中國開發(fā)者網(wǎng)站Google Developers搀缠,查看官方學(xué)習(xí)資源再也不用爬梯子了
- 簡介
- 使用說明
- ContentObserver
簡介
ContentProvider即內(nèi)容提供者,是Android的四大組件之一近迁。內(nèi)容提供者是應(yīng)用程序之間共享數(shù)據(jù)的接口艺普,Android系統(tǒng)將這種機(jī)制應(yīng)用到方方面面。
比如:聯(lián)系人Provider專為不同應(yīng)用程序提供聯(lián)系人數(shù)據(jù);設(shè)置Provider專為不同應(yīng)用程序提供系統(tǒng)配置信息歧譬,包括內(nèi)置的設(shè)置應(yīng)用程序等岸浑。當(dāng)應(yīng)用繼承ContentProvider類,并重寫該類用于提供數(shù)據(jù)和存儲數(shù)據(jù)的方法瑰步,就可以向其他應(yīng)用共享其數(shù)據(jù)矢洲。
雖然使用其他方法也可以對外共享數(shù)據(jù),但數(shù)據(jù)訪問方式會因數(shù)據(jù)存儲的方式而不同缩焦,如:采用文件方式對外共享數(shù)據(jù)读虏,需要進(jìn)行文件操作讀寫數(shù)據(jù);采用SharedPreferences共享數(shù)據(jù)舌界,需要使用SharedPreferences API讀寫數(shù)據(jù)掘譬。
而使用ContentProvider共享數(shù)據(jù)的好處是統(tǒng)一了數(shù)據(jù)訪問方式泰演。內(nèi)容提供者將數(shù)據(jù)封裝呻拌,只暴露出我們希望提供給其他程序的數(shù)據(jù)。內(nèi)容提供者中數(shù)據(jù)更改可被監(jiān)聽睦焕。
使用說明
- 定義類繼承ContentProvider藐握,根據(jù)需要重寫內(nèi)部方法(增刪改查)
- 在清單文件的<application>節(jié)點下進(jìn)行配置,<provider>標(biāo)簽中需要指定name和authorities屬性
name:類名垃喊,包名從程序Package開始猾普,以“.”開始
authorities:是訪問Provider時的路徑,要唯一 - URI代表要操作的數(shù)據(jù)本谜,由scheme初家、authorites、path三部分組成
content://cn.gunther.sqlite.provider/person
scheme:固定為content溜在,代表訪問內(nèi)容提供者
authorites:<provider>節(jié)點中的authorites屬性
path:程序定義的路徑,可根據(jù)業(yè)務(wù)邏輯定義
示例代碼:
- 新建一個工程MyContentProvider他托,包名:com.gunther.provider掖肋。
- 在com.gunther.provider.dao包下新建PersonOpenHelper類繼承SQLiteOpenHelper類,該類用于創(chuàng)建數(shù)據(jù)庫赏参。
public class PersonOpenHelper extends SQLiteOpenHelper {
public PersonOpenHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
public PersonOpenHelper(Context context){
super(context, "person.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table person (id integer primary key autoincrement,name varchar(20),phone varchar(20),age integer,address varchar(50));";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
-
在com.gunther.contenProvider.provider包中創(chuàng)建志笼,PersonContentProvider類繼承ContentProvider類。同時將該P(yáng)rovider在AndroidManifest.xml中注冊把篓。
<provider android:exported="true" android:name="com.gunther.contenProvider.provider.PersonContentProvider" android:authorities="com.gunther.person" /> public class PersonContentProvider extends ContentProvider { //用于存放并匹配個Uri標(biāo)識信息纫溃,一般在靜態(tài)代碼塊中對其信息進(jìn)行初始化操作 private static UriMatcher matcher; //聲明一個用于操作數(shù)據(jù)庫對象 private PersonOpenHelper openHelper; //主機(jī)名信息:對應(yīng)清單文件的authorities屬性 private static final String AUTHORITY = "com.gunther.person"; //數(shù)據(jù)庫 表名 private static final String TABLE_PERSON_NAME = "person"; //Uri匹配成功的返回碼 private static final int PERSON_INSERT_CODE = 1000; private static final int PERSON_DELETE_CODE = 10001; private static final int PERSON_UPDATE_CODE = 10002; private static final int PERSON_QUERYALL_CODE = 10003; private static final int PERSON_QUERYONE_CODE = 10004; //靜態(tài)代碼塊,用于初始化UriMatcher static{ //NO_MATCH:沒有Uri匹配的時候返回的狀態(tài)碼(-1) matcher = new UriMatcher(UriMatcher.NO_MATCH); //添加一個分機(jī)號: //對person表進(jìn)行添加操作韧掩,如果Uri=content://com.gunther.person/person/insert,則返回PERSON_INSERT_CODE matcher.addURI(AUTHORITY, "person/insert", PERSON_INSERT_CODE); //對person表進(jìn)行刪除操作,如果Uri= content://com.gunther.person/person/delete,則返回PERSON_DELETE_CODE matcher.addURI(AUTHORITY, "person/delete", PERSON_DELETE_CODE); //對person表進(jìn)行修改操作,如果Uri= content://com.gunther.person/person/update,則返回PERSON_UPDATE_CODE matcher.addURI(AUTHORITY, "person/update", PERSON_UPDATE_CODE); //對person表進(jìn)行查詢所有操作,如果Uri= content://com.gunther.person/person,則返回PERSON_QUERYALL_CODE matcher.addURI(AUTHORITY, "person", PERSON_QUERYALL_CODE); //對person表進(jìn)行查詢單個操作,如果Uri= content://com.gunther.person/person/#,(#:代表數(shù)字)則返回PERSON_QUERYONE_CODE matcher.addURI(AUTHORITY, "person/#", PERSON_QUERYONE_CODE); } @Override public boolean onCreate() { //內(nèi)容提供者中紊浩,獲取contenxt,是通過getContext,與測試類一樣郎楼,不能再成員變量万伤,構(gòu)造函數(shù)中調(diào)用,但是可以再onCreate方法中獲取呜袁。 openHelper = new PersonOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //用匹配器去匹配uri敌买,如果匹配成功則返回匹配器中對應(yīng)的狀態(tài)碼 int matchCode = matcher.match(uri); SQLiteDatabase db = openHelper.getReadableDatabase(); switch (matchCode) { case PERSON_QUERYALL_CODE: return db.query(TABLE_PERSON_NAME, projection, selection, selectionArgs, null, null, sortOrder); case PERSON_QUERYONE_CODE: //使用ContentUris工具類解析出uri中的id long parseId = ContentUris.parseId(uri); return db.query(TABLE_PERSON_NAME, projection,"id=?", new String[]{parseId+""}, null, null, sortOrder); default: throw new IllegalArgumentException("Uri匹配失敗:"+uri); }} @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = openHelper.getWritableDatabase(); //新插入對象的id long id = db.insert(TABLE_PERSON_NAME, null, values); db.close(); //使用ContentUris工具類將id追加到uri中阶界,返回給客戶 return ContentUris.withAppendedId(uri, id); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = openHelper.getWritableDatabase(); //返回刪除的個數(shù) int count = db.delete(TABLE_PERSON_NAME, selection, selectionArgs); //關(guān)閉數(shù)據(jù)庫 db.close(); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = openHelper.getWritableDatabase(); //返回更新的個數(shù) int count = db.update(TABLE_PERSON_NAME, values, selection, selectionArgs); //更新數(shù)據(jù)庫 db.close(); return count; } @Override public String getType(Uri uri) { return null; } }
?
ContentObserver
ContentObserver——內(nèi)容觀察者虹钮,目的是觀察(捕捉)特定Uri引起的數(shù)據(jù)庫的變化,繼而做一些相應(yīng)的處理膘融,它類似于數(shù)據(jù)庫技術(shù)中的觸發(fā)器(Trigger)芙粱,當(dāng)ContentObserver所觀察的Uri發(fā)生變化時,便會觸發(fā)它氧映。觸發(fā)器分為表觸發(fā)器春畔、行觸發(fā)器,相應(yīng)地ContentObserver也分為“表“ContentObserver岛都、“行”ContentObserver律姨,當(dāng)然這是與它所監(jiān)聽的Uri MIME Type有關(guān)的。
private class AppLockObserver extends ContentObserver{
public AppLockObserver(){
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//觀察到注冊的uri數(shù)據(jù)發(fā)送變化臼疫,根據(jù)業(yè)務(wù)需求處理
}
}