天天看點

ContentProvider那些事兒(一)

1 簡介

本篇将對内容提供者做個介紹,并做個簡單的實踐。

内容提供者簡單來說就是就是實作不同應用之間資料共享的一種方式。

通常情況下,android應用隻需要使用自己應用的沙盒中管理資料,實作資料的CRUD操作即可;然而,有很多種情況,我們需要共享資料,比如擷取手機聯系人,又或者自己開發的兩款應用需要通路共有的使用者系統。

2 資料共享方式

這裡總結android開發中資料共享的方式:

  • SharePreference

    兩個應用直接均需使用同一套API進行通路,且資料量較小,局限性較強,CRUD操作效率較低。

  • ContentProvider

    ContentProvider對資料的共享提供了一套标準的機制,無論存儲者使用何種方式存儲資料,調用者都無需關心,相對來說更加友善。由于ContentResolver無需關心存儲技術的實作和細節,是以無論資料量的大小,都可以采用該方案實作。

  • sharedUserId

    兩個應用直接均需使用同一套API進行通路,且資料量較小,局限性較強,CRUD操作效率較低。還需要求應用打包簽名一緻等條件,單純為了資料存儲,代價有點高了。

  • 檔案讀寫

    兩個應用直接均需使用同一套API進行通路,且資料量較小,CRUD操作效率較低。

3 實踐

ContentProvider端主要代碼

public class PersonContentProvider extends ContentProvider {
    private final String TAG = "hh";
    private PersonDao personDao = null;
    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int PERSON  = 1;
    private static final int PERSONS = 2;
    static {
        URI_MATCHER.addURI("com.example.studentProvider","person",PERSONS);
        URI_MATCHER.addURI("com.example.studentProvider",
               "person/#", PERSON);
    }
    @Override
    public Bundle call(String method, String arg, Bundle extras) {
        Log.i(TAG, "--->>" + method);
        Bundle bundle = new Bundle();
        bundle.putString("returnCall", "call被執行了");
        return bundle;
    }
    @Override
    public boolean onCreate() {
        personDao = new PersonDao(getContext());
        Log.i(TAG,"onCreate");
        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        Cursor cursor = null;
        int flag = URI_MATCHER.match(uri);
        if(flag == PERSON)
        {
            long id = ContentUris.parseId(uri);
            Log.i(TAG,"查詢,id=" + id);
            String where_value = " id = ?";
            String[] args = {String.valueOf(id)};
            cursor = personDao.queryPersons(where_value,args);
        }else
        {
            cursor = personDao.queryPersons(selection,selectionArgs);
        }
        return cursor;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        int flag = URI_MATCHER.match(uri);
        switch (flag)
        {
            case PERSON:
                return "vnd.android.cursor.item/person";
            case PERSONS:
                return "vnd.android.cursor.dir/persons";
        }
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        Uri resultUri = null;
        int flag = URI_MATCHER.match(uri);
        if(flag == PERSONS)
        {
            long id = personDao.insertPerson(values);
            resultUri = ContentUris.withAppendedId(uri,id);
            Log.i(TAG,"插入成功,id="+id);
            Log.i(TAG,"插入成功,resultUri="+resultUri.toString());
        }
        return resultUri;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        int count = -1;
        int flag = URI_MATCHER.match(uri);
        if(flag == PERSON)
        {
         long id = ContentUris.parseId(uri);
         String where_value = "id = ?";
         String[] args = {String.valueOf(id)};
         count = personDao.deletePerson(where_value,args);
        }else{
            count = personDao.deletePerson(selection,selectionArgs);
        }
        Log.i(TAG,"删除成功,count = " + count);
        return count;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        int count = -1;
        int flag = URI_MATCHER.match(uri);
        if(flag == PERSON)
        {
            long   id = ContentUris.parseId(uri);
            String where_value = "id = ?";
            String[] args = {String.valueOf(id)};
            count = personDao.updatePerson(values,where_value,args);
        }else
        {
            count = personDao.updatePerson(values,selection,selectionArgs);
        }
        Log.i(TAG,"更新成功,count=" + count);
        return count;
    }
}
  <provider
            android:exported="true"
            android:authorities="com.example.studentProvider"
            android:name="com.example.wanghaoqiang.contentproviderdemo.PersonContentProvider"></provider>
    
           

這裡需要注意的是xml中的android:authorities需要和URI_MATCHER.addURI(“com.example.studentProvider”,“person”,PERSONS);加入的authorities一緻,同時android:exported="true"記住一定要設定,不然其他程序無法通路。

ContentResolver端的主要代碼

ContentResolver contentResolver = getApplicationContext().getContentResolver();
                Uri uri = Uri.parse("content://com.example.studentProvider/person");
                ContentValues values = new ContentValues();
                values.put("name", "生命貳号");
                values.put("address", "湖北");
                contentResolver.insert(uri,values);
           

4 源碼位址

點選下載下傳源碼

繼續閱讀