Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android四大组件之ContentProvider #9

Open
zgq105 opened this issue Apr 27, 2019 · 0 comments
Open

Android四大组件之ContentProvider #9

zgq105 opened this issue Apr 27, 2019 · 0 comments

Comments

@zgq105
Copy link
Owner

zgq105 commented Apr 27, 2019

ContentProvider
image

1. 什么是ContentProvider?作用是什么?

ContentProvider是安卓四大组件之一,它是一种Android应用之间数据共享的机制。它主要是通过一种协议规则进行应用之间的数据共享,比如,我们调用手机通讯录的时候使用的就是一种内容提供者的实现。

2. ContentProvider通信基础

ContentProvider通信的基础是基于Uri(统一资源标识符)的机制,外界应用程序就是通过Uri来获取到对应的内容提供者,从起对其进行增删改查的操作。内容提供者的URI格式如下:
content://com.zgq.provider/User/1,其中content表示的是内容提供者的协议格式;com.zgq.provider表示的是授权信息authority,为了增强识别度,命名通常是包名+xxProvider;/User/1是路径部分,其中User表示某个实体,可以理解某个表,而1表示某个表的某条记录。

URI两个常用通配符*和#
表示匹配任意长度的任何有效字符的字符串,比如content://com.zgq.provider/,表示匹配这个内容提供者的所有信息。
#表示匹配任意长度的数字字符的字符串,比如content://com.zgq.provider/User/#,表示匹配这个内容提供者User表中的所有记录。

MIME类型有2种形式:

  1. 单条记录:vnd.android.cursor.item/自定义
  2. 多条记录:vnd.android.cursor.dir/自定义

3. 构建ContentProvider

自定义内容提供者主要是通过实现ContentProvider抽象类,并重写实现内部增删改查的方法。
//示例代码

public class ContentProvider1 extends ContentProvider {

    private static final UriMatcher mMatcher;
    private static final String AUTHORITY = "com.zgq.android_demo.cp_demo.contentProvider1";
    private static final int TB1_CODE = 1;//表1标识码
    private static final int TB2_CODE = 2;//表2标识码

    private SQLiteDatabase mSQLiteDatabase;
    private DbHelper mDbHelper;

    static {
        //初始化UriMatcher对象
        mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        mMatcher.addURI(AUTHORITY, "tb1", TB1_CODE);
        mMatcher.addURI(AUTHORITY, "tb2", TB2_CODE);
        // 若URI资源路径 = content://com.zgq.android_demo.cp_demo.contentProvider1/tb1 ,则返回注册码TB1_CODE
        //若URI资源路径 = content://com.zgq.android_demo.cp_demo.contentProvider1/tb2 ,则返回注册码TB2_CODE

    }

    @Override
    public boolean onCreate() {
        mDbHelper = new DbHelper(getContext());
        mSQLiteDatabase = mDbHelper.getWritableDatabase();
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        return mSQLiteDatabase.query(getTableName(uri), projection, selection, selectionArgs, null, null, sortOrder);
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }


    @Override
    public Uri insert(Uri uri, ContentValues values) {
        mSQLiteDatabase.insert(getTableName(uri), null, values);
        return uri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }


    private String getTableName(Uri uri) {
        String tbName = null;
        switch (mMatcher.match(uri)) {
            case TB1_CODE: {
                tbName = "tb1";
                break;
            }
            case TB2_CODE: {
                tbName = "tb2";
                break;
            }
            default:
                break;
        }

        return tbName;
    }
}

关键API: UriMatcher,Uri;其中UriMatcher主要建立Uri和表的映射关系,根据调用方传入的Uri,便可以通过UriMatcher找到对应的表,进而进行操作。

4. 使用ContentProvider

使用ContentProvider主要用到Uri和ContentResolver类,其中Uri标识要操作的是哪个内容提供者,而ContentResolver封装好了和ContentProvider 对应的API用于操作对应的数据。
//示例代码:

//插入
ContentValues values = new ContentValues();
values.put("id", 1);
values.put("name", "zgq");
this.getContentResolver().insert(uri, values);

//查询
this.getContentResolver().query(uri, null, "id=?", new String[]{"1"}, null);

5. 小结

关于内容提供者的几点小结:
1. 内容提供者是跨进程共享数据的一种机制,通过统一的API操作方式对外提供数据。
2. 数据提供方主要继承ContentProvider类,实现好对外共享的数据资源;而调用方主要通过ContentResolver和Uri来操作对应的数据资源。
3. 内容提供者是通过Uri协议格式交换对应数据的。
4. 内容提供者内部的通信机制是通过Binder机制实现的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant