說明:文章僅供本人學習記錄所用。java
1.理解含義:android
ContentProvider: 內容提供者,將數據以表的形式進行操做。主要實現應用程序間數據共享,操做系統本地數據(包括短 信、音頻、視屏、數據庫)。數據庫
ContentObserver:內容觀察者,監聽數據變化。
安全
2.使用方法:併發
ContentProvider:ide
1)步驟:新建MyProvider類繼承ContentProvider類;註冊URI;重寫方法(onCreate、query、bulkInsert、insert、 delete、update);在AndroidManifest.xml中配置provider;學習
2)代碼:spa
public class MyProvider extends ContentProvider { private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int INSERT = 1; private static final int UPDATE = 2; private static final int DELETE = 3; private static final int QUERY = 4; private static final int INSERTS = 5; private DBHelper dbOpenHelper; private String TAG = "Provider"; static { // 爲UriMatcher註冊si四個Uri matcher.addURI(Picture.AUTHORITY, "insert", INSERT); matcher.addURI(Picture.AUTHORITY, "update", UPDATE); matcher.addURI(Picture.AUTHORITY, "delete", DELETE); matcher.addURI(Picture.AUTHORITY, "query", QUERY); matcher.addURI(Picture.AUTHORITY, "inserts", INSERTS); //說明Picture.AUTHORITY:表示你要操做的ContentProvider,通常以要操做的實體類的包名命名。 } @Override public boolean onCreate() { //獲取數據庫輔助類 dbOpenHelper = DBHelper.getInstance(getContext()); DatabaseManager.initializeInstance(dbOpenHelper); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub int code = matcher.match(uri); Cursor c = null; switch (code) { case QUERY: SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); c = database.query("picture", projection, selection, selectionArgs, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); DatabaseManager.getInstance().closeDatabase(); case UriMatcher.NO_MATCH: Log.i(TAG, "------------未知的URI" + uri); break; } return c; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { int code = matcher.match(uri); switch (code) { case INSERT: SQLiteDatabase database = DatabaseManager.getInstance() .openDatabase();// 線程安全併發操做數據庫 try {// 得到數據庫實例 database.insert("picture", null, values); getContext().getContentResolver().notifyChange(uri, null); } catch (Exception ex) { Log.i(TAG, "insert ex=====" + ex.toString()); } finally { DatabaseManager.getInstance().closeDatabase(); } break; case UriMatcher.NO_MATCH: Log.i(TAG, "------------未知的URI" + uri); break; } return null; } /** * 批量插入 */ @Override public int bulkInsert(Uri uri, ContentValues[] values) { int code = matcher.match(uri); switch (code) { case INSERTS: SQLiteDatabase database = DatabaseManager.getInstance() .openDatabase();// 線程安全併發操做數據庫 try {// 得到數據庫實例 int numValues = 0; numValues = values.length; for (int i = 0; i < numValues; i++) { ContentValues value = values[i]; database.delete("picture", "name = ?", new String[] { String.valueOf(value.get("name")) }); Log.i(TAG, "name===== values" + String.valueOf(value.get("name"))); database.insert("picture", null, values[i]); Log.i(TAG, "Value insert====" + i); } getContext().getContentResolver().notifyChange(uri, null); } catch (Exception ex) { Log.i(TAG, "insert ex=====" + ex.toString()); } finally { DatabaseManager.getInstance().closeDatabase(); } break; case UriMatcher.NO_MATCH: Log.i(TAG, "------------未知的URI" + uri); break; } return 0; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int code = matcher.match(uri); switch (code) { case DELETE: SQLiteDatabase database = DatabaseManager.getInstance() .openDatabase(); int i = 0; try { i = database.delete("picture", selection, selectionArgs); if (i > 0) { getContext().getContentResolver().notifyChange(uri, null); } } catch (Exception ex) { Log.i(TAG, "delete ex====" + ex.toString()); } finally { // database.close(); DatabaseManager.getInstance().closeDatabase(); } return i; case UriMatcher.NO_MATCH: Log.i(TAG, "------------未知的URI" + uri); break; } return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int code = matcher.match(uri); switch (code) { case UPDATE: // SQLiteDatabase database = dbOpenHelper.getReadableDatabase(); SQLiteDatabase database = DatabaseManager.getInstance() .openDatabase(); int i = 0; try { i = database .update("picture", values, selection, selectionArgs); if (i != 0) { getContext().getContentResolver().notifyChange(uri, null); } } catch (Exception ex) { Log.i(TAG, "update ex===" + ex.toString()); } finally { // database.close(); DatabaseManager.getInstance().closeDatabase(); } return i; case UriMatcher.NO_MATCH: Log.i(TAG, "------------未知的URI" + uri); break; } return 0; } } //在數據庫操做類中添加如下方法。 //單條數據添加 public static void addPicture(Picture picture) { Uri uri = Uri.parse("content://" + Picture.AUTHORITY + "/insert"); ContentValues values = new ContentValues();//封裝數據 values.put("name", picture.name); ... AppApplication.getInstance().getContentResolver().insert(uri, values); } //多條數據添加 public static void addPictures(List<Picture> pictures) { Uri uri = Uri.parse("content://" + Picture.AUTHORITY + "/inserts"); ContentValues[] values = new ContentValues[pictures.size()]; for (int i = 0; i < pictures.size(); i++) { Picture picture = pictures.get(i); ContentValues value = new ContentValues(); value.put("name", picture.name); ... values[i] = value; } Log.i(TAG, "addPictures_values_size=====" + values.length); AppApplication.getInstance().getContentResolver().bulkInsert(uri, values); } //刪除操做 public static void deletePictureTag() { Uri uri = Uri.parse("content://" + Picture.AUTHORITY + "/delete"); int i = AppApplication.getInstance().getContentResolver() .delete(uri, "whereName = ?", new String[] { "value" }); } //修改操做 public static void updatePicture(Picture picture) { Uri uri = Uri.parse("content://" + Picture.AUTHORITY + "/update"); ContentValues values = new ContentValues(); values.put("tagStatus", picture.tagStatus); int i = AppApplication.getInstance().getContentResolver() .update(uri, values, "whereName = ?", new String[] { picture.name }); } //AndroidManifest.xml中配置provider <provider android:name="com....provider.MyProvider"//包名 android:authorities="com....provider.myProvide" />
ContentObserver:線程
1)步驟:註冊與註銷ContentObserver;添加ContentObserver方法。code
2)代碼:
//uri與provider中註冊的uri對應 Uri uri = Uri.parse("content://" + Picture.AUTHORITY + "/insert");//監聽添加 getContentResolver().registerContentObserver(uri, true, cob); Uri uri_inserts = Uri.parse("content://" + Picture.AUTHORITY+ "/inserts");//監聽批量添加 getContentResolver().registerContentObserver(uri_inserts, true, cob); Uri uri_update = Uri.parse("content://" + Picture.AUTHORITY + "/update");//監聽修改 getContentResolver().registerContentObserver(uri_update, true, cob); getContentResolver().unregisterContentObserver(cob);//在onDestroy銷燬 //監聽數據改變的方法 private ContentObserver cob = new ContentObserver(new Handler()) { @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //改變數據時作出相應的操做 ...... } }