欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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能够跨进程的存储数据,通过调用相对应的方法能够增、删、改、查。