Android開發:ContentProvider例項詳解
- 2016年12月8日,Google中國開發者大會在京舉行,同時正式上線了Google中國開發者網站Google Developers,檢視官方學習資源再也不用爬梯子了
- 簡介
- 使用說明
- ContentObserver
簡介
ContentProvider即內容提供者,是Android的四大元件之一。內容提供者是應用程式之間共享資料的介面,Android系統將這種機制應用到方方面面。
比如:聯絡人Provider專為不同應用程式提供聯絡人資料;設定Provider專為不同應用程式提供系統配置資訊,包括內建的設定應用程式等。當應用繼承ContentProvider類,並重寫該類用於提供資料和儲存資料的方法,就可以向其他應用共享其資料。
雖然使用其他方法也可以對外共享資料,但資料訪問方式會因資料儲存的方式而不同,如:採用檔案方式對外共享資料,需要進行檔案操作讀寫資料;採用SharedPreferences共享資料,需要使用SharedPreferences API讀寫資料。
而使用ContentProvider共享資料的好處是統一了資料訪問方式。內容提供者將資料封裝,只暴露出我們希望提供給其他程式的資料。內容提供者中資料更改可被監聽。
使用說明
- 定義類繼承ContentProvider,根據需要重寫內部方法(增刪改查)
- 在清單檔案的<application>節點下進行配置,<provider>標籤中需要指定name和authorities屬性
name:類名,包名從程式Package開始,以“.”開始
authorities:是訪問Provider時的路徑,要唯一 - URI代表要操作的資料,由scheme、authorites、path三部分組成
content://cn.gunther.sqlite.provider/person
scheme:固定為content,代表訪問內容提供者
authorites:<provider>節點中的authorites屬性
path:程式定義的路徑,可根據業務邏輯定義
示例程式碼:
- 新建一個工程MyContentProvider,包名:com.gunther.provider。
- 在com.gunther.provider.dao包下新建PersonOpenHelper類繼承SQLiteOpenHelper類,該類用於建立資料庫。
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包中建立,PersonContentProvider類繼承ContentProvider類。同時將該Provider在AndroidManifest.xml中註冊。
<provider android:exported="true" android:name="com.gunther.contenProvider.provider.PersonContentProvider" android:authorities="com.gunther.person" /> public class PersonContentProvider extends ContentProvider { //用於存放並匹配個Uri標識資訊,一般在靜態程式碼塊中對其資訊進行初始化操作 private static UriMatcher matcher; //宣告一個用於運算元據庫物件 private PersonOpenHelper openHelper; //主機名資訊:對應清單檔案的authorities屬性 private static final String AUTHORITY = "com.gunther.person"; //資料庫 表名 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; //靜態程式碼塊,用於初始化UriMatcher static{ //NO_MATCH:沒有Uri匹配的時候返回的狀態碼(-1) matcher = new UriMatcher(UriMatcher.NO_MATCH); //新增一個分機號: //對person表進行新增操作,如果Uri=content://com.gunther.person/person/insert,則返回PERSON_INSERT_CODE matcher.addURI(AUTHORITY, "person/insert", PERSON_INSERT_CODE); //對person表進行刪除操作,如果Uri= content://com.gunther.person/person/delete,則返回PERSON_DELETE_CODE matcher.addURI(AUTHORITY, "person/delete", PERSON_DELETE_CODE); //對person表進行修改操作,如果Uri= content://com.gunther.person/person/update,則返回PERSON_UPDATE_CODE matcher.addURI(AUTHORITY, "person/update", PERSON_UPDATE_CODE); //對person表進行查詢所有操作,如果Uri= content://com.gunther.person/person,則返回PERSON_QUERYALL_CODE matcher.addURI(AUTHORITY, "person", PERSON_QUERYALL_CODE); //對person表進行查詢單個操作,如果Uri= content://com.gunther.person/person/#,(#:代表數字)則返回PERSON_QUERYONE_CODE matcher.addURI(AUTHORITY, "person/#", PERSON_QUERYONE_CODE); } @Override public boolean onCreate() { //內容提供者中,獲取contenxt,是通過getContext,與測試類一樣,不能再成員變數,建構函式中呼叫,但是可以再onCreate方法中獲取。 openHelper = new PersonOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //用匹配器去匹配uri,如果匹配成功則返回匹配器中對應的狀態碼 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(); //返回刪除的個數 int count = db.delete(TABLE_PERSON_NAME, selection, selectionArgs); //關閉資料庫 db.close(); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = openHelper.getWritableDatabase(); //返回更新的個數 int count = db.update(TABLE_PERSON_NAME, values, selection, selectionArgs); //更新資料庫 db.close(); return count; } @Override public String getType(Uri uri) { return null; } }
ContentObserver
ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引起的資料庫的變化,繼而做一些相應的處理,它類似於資料庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它。觸發器分為表觸發器、行觸發器,相應地ContentObserver也分為“表“ContentObserver、“行”ContentObserver,當然這是與它所監聽的Uri MIME Type有關的。
private class AppLockObserver extends ContentObserver{
public AppLockObserver(){
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//觀察到註冊的uri資料傳送變化,根據業務需求處理
}
}
相關文章
- android widget 開發例項 : 桌面便籤程式的實現詳解和源Android
- Java開發中的事件驅動模型例項詳解Java事件模型
- OC開發例項變數的訪問控制詳解變數
- curl例項詳解
- sudo 詳解+例項
- Android ContentProvider 基本原理和使用詳解AndroidIDE
- android移動開發簡單的開發例項Android移動開發
- android原生開發recyclerview基礎例項AndroidView
- 元件例項 $el 詳解元件
- Crontab例項-命令詳解
- tcl/tk例項詳解——glob使用例解
- Android 中Message,MessageQueue,Looper,Handler詳解+例項AndroidOOP
- 並查集例項詳解並查集
- Oracle 例項恢復詳解Oracle
- Android開發規範詳解Android
- ANDROID開發之SQLite詳解AndroidSQLite
- Android開發 - RecyclerView 類詳解AndroidView
- Android開發 - Movie 類詳解Android
- EventBus詳解及簡單例項單例
- CSS例項詳解:Flex佈局CSSFlex
- PHP生成日曆(例項詳解)PHP
- FTP命令詳解(含操作例項)FTP
- python閉包詳解(例項)Python
- .Net設計模式例項詳解設計模式
- 【函式】oracle translate() 詳解+例項函式Oracle
- linux中sleep詳解例項Linux
- 例項詳解不同VLAN間通訊(轉發過程)
- Android API開發之OpenGL開發之Android OpenGL STL詳解AndroidAPI
- Android進階知識樹——ContentProvider使用和工作過程詳解AndroidIDE
- Android-國際化(多語言)切換詳解及例項Android
- PHP7 新增功能詳解(例項)PHP
- Spring事務管理(詳解+例項)Spring
- 50個典型電路例項詳解
- 閉包用法結合例項詳解
- Oracle阻塞(blockingblocked)例項詳解OracleBloC
- tcl/tk例項詳解——catch和errorError
- MySQL共享鎖:使用與例項詳解MySql
- Android APK開發:Menu介面功能詳解AndroidAPK