android存储方式之ContentProvider存储方式讲解
程序员文章站
2024-01-19 12:07:52
android的五种存储方式分别是:
1,SharedPreferences
2,file
3,sqlite
4,contentproviter
5,http
Cont...
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能够跨进程的存储数据,通过调用相对应的方法能够增、删、改、查。