android的五種存儲方式分別是:
1,SharedPreferences
2,file
3,sqlite
4,contentproviter
5,http
ContentProvider
註意:
大多數ContentProvider使用Android文件系統或者SQLite數據庫來保持數據,但是也可以以任何方式來存儲。
在清單文件中註冊一個自定義ContentProviter
重寫一個TestContentProvider類繼承ContentProviter
public class TestContentProvider extends ContentProvider { //這裡的AUTHORITY就是我們在AndroidManifest.xml中配置的authorities public static final String AUTHORITY = "com.lh.knowledge.contentprovider"; //匹配成功後的匹配碼 private static final int MATCH_ALL_CODE = 100; private static final int MATCH_ONE_CODE = 101; private static UriMatcher uriMatcher;//uri匹配器 private Cursor cursor = null;//遊標 List testBeanList = new ArrayList<>(); @Override public boolean onCreate() { initData(); //添加要匹配的uri,匹配不成功返回NO_MATCH(-1) uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); /** * uriMatcher.addURI(authority, path, code); 其中 * authority:主機名(用於唯一標示一個ContentProvider,這個需要和清單文件中的authorities屬性相同) * path:路徑路徑(可以用來表示我們要操作的數據,路徑的構建應根據業務而定) * code:返回值(用於匹配uri的時候,作為匹配成功的返回值) */ uriMatcher.addURI(AUTHORITY, "student", MATCH_ALL_CODE);// 匹配記錄集合 uriMatcher.addURI(AUTHORITY, "student/#", MATCH_ONE_CODE);// 匹配單條記錄 return false; } private void initData() { TestBean testBean1 = new TestBean(); testBean1.setId(1); testBean1.setName("aaa"); testBean1.setPrice(5.2); testBean1.setSex(false); testBeanList.add(testBean1); TestBean testBean2 = new TestBean(); testBean1.setId(2); testBean1.setName("bbb"); testBean1.setPrice(6.2); testBean1.setSex(true); testBeanList.add(testBean2); TestBean testBean3 = new TestBean(); testBean1.setId(3); testBean1.setName("ccc"); testBean1.setPrice(0.2); testBean1.setSex(false); testBeanList.add(testBean3); } /** * @param uri * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return */ @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { //這裡的查詢需要配合sqlite來使用 return null; } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { int match = uriMatcher.match(uri); if (match != MATCH_ALL_CODE) {//這裡不能匹配集合,隻能匹配單個 throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); } // int indexId = values.getAsInteger("indexId"); Uri insertUri = ContentUris.withAppendedId(uri, indexId); if (indexId > 0) { TestBean testBean = new TestBean(); testBean.setId(indexId); testBean.setName("content provider userid " + indexId); testBeanList.add(testBean); return insertUri; } return null; } @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { //匹配uri switch (uriMatcher.match(uri)) { case MATCH_ALL_CODE://集合 int i = testBeanList.size(); testBeanList.clear(); return i; case MATCH_ONE_CODE://單個 int postion = Integer.parseInt(selection); testBeanList.remove(postion); return 1; default://拋出異常,沒有匹配到uri //throw new IllegalArgumentException("Unkwon Uri:" + uri.toString()); return 0; } } @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { int postion = Integer.parseInt(selection); if (postion > testBeanList.size() - 1) return 0; TestBean testBean = testBeanList.get(postion); if (testBean == null) return 0; String name = values.getAsString("name"); testBean.setName(name); return 1; } }
如何使用ContentProvider來存儲數據
public class ContentProviderActivity extends Activity { private ContentResolver contentResolver; private final Uri STUDENT_ALL_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student"); private final Uri STUDENT_ONE_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student/#"); private Handler handler = new Handler() { public void handleMessage(Message msg) { //這裡說明內容提供者的uri正確,隨機操作增刪改查 /** * @param uri * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return cursor */ Cursor cursorAll = contentResolver.query(STUDENT_ALL_URI, null, null, null, null); //查詢userid為1的用戶 Cursor cursorOne = contentResolver.query(STUDENT_ONE_URI, null, "1", null, null); //刪除userid為2的用戶,返回當前刪除條數 int i = contentResolver.delete(STUDENT_ONE_URI, "2", null); //修改 ContentValues contentValues = new ContentValues(); contentValues.put("name", "test"); int updateNumber = contentResolver.update(STUDENT_ONE_URI, contentValues, "1", null); //這裡的方法都與TestContentProvider中的方法相對應 } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //獲得內容提供者解析器 contentResolver = getContentResolver(); //註冊內容觀察者 contentResolver.registerContentObserver(STUDENT_ALL_URI, true, new PersonOberserver(handler)); } /** * 觀察者,如果找到瞭當前uri的提供者,則會回調 */ public class PersonOberserver extends ContentObserver { private Handler handler; public PersonOberserver(Handler handler) { super(handler); this.handler = handler; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //向handler發送消息,找到瞭當前的提供者 Message msg = new Message(); handler.sendMessage(msg); } }
ContentProviter能夠跨進程的存儲數據,通過調用相對應的方法能夠增、刪、改、查。