1. 程式人生 > >Android四大元件之ContentProvider內容提供器

Android四大元件之ContentProvider內容提供器

public class MyProvider extends ContentProvider{
    
    public static final int TABLE1_DIR = 0;
    public static final int TABLE1_ITEM = 1;
    public static final int TABLE2_DIR = 2;
    public static final int TABLE1_ITEM = 3;
    
    private static UriMatcher uriMatcher;
    
    static{
        uriMatcher = new UriMatcher(Uri.Matcher.NO_MATCH);
        //第一個引數為authority(一般為應用包名.provider)
        //第二個引數為path,即查詢的表
        //第三個引數為自定義碼
        uriMatcher.addUri("com.example.app.provider","table1",TABLE1_DIR);
        uriMatcher.addUri("com.example.app.provider","table1/#",TABLE1_ITEM);
        uriMatcher.addUri("com.example.app.provider","table2",TABLE2_DIR);
        uriMatcher.addUri("com.example.app.provider","table2/#",TABLE2_ITEM);
    }
    
    @Override
    public boolean OnCreate(){
        /*
        初始化內容提供器時呼叫,一般在這裡完成資料庫的建立與升級等操作
        (只在有呼叫ContentResolver嘗試訪問app中的資料時,才會被初始化)
        */
        return false;//返回true代表初始化成功,false則為失敗
    }
    
    @Override
    public Cursor query(Uri uri,String[] projection,String selection,
                        String[] selectionArgs,String sortOrder){
        /*
        呼叫該方法從內容提供器中查詢資料,uri引數用作確定查詢的表
        projection引數用於確定查詢的列,selection,selectionArgs是查詢的條件
        sortOrder是對結果進行排序
        
        查詢結果存放在Cursor物件中返回
        */
        //其他方法中也類似,呼叫uriMatcher匹配查詢的位置
        switch(uriMatcher.match(uri)){
            case TABLE1_DIR:
                //查詢該表的全部資料
                break;
            case TABLE1_ITEM:
                //查詢該表下的某條資料
                break;
            case TABLE2_DIR:
                //同理
                break;
            case TABLE1_ITEM:
                //同理
                break;
        }
        return null;
    }
    
    @Override
    public Uri insert(Uri uri,ContentValues values){
        /*
        想內容提供器中插入一條資料
        uri:確定插入的表
        values:插入的資料
        
        新增成功後會返回表示該條新資料的uri
        */
        return null;
    }
    
    @Override
    public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs){
        /*
        更新資料時呼叫該方法
        uri:同理
        values:新的資料
        selection、selectionArgs:更新的條件
        
        返回更新了的行數
        */
        return 0;
    }
    
    @Override
    public int delete(Uri uri,String selection,String[] selectionArgs){
        /*
        刪除資料時呼叫
        uri:同理
        selection、selectionArgs:同理
        
        返回被刪除的行數
        */
        return 0;
    }
    
    @Override
    public String getType(Uri uri){
        /*
        呼叫該方法,是根據傳入的uri返回相應的MIME型別
        MIME字串主要由3部分組成:
        1.vnd開頭
        2.如果URI以路徑結尾,則後接android.cursor.dir/,
        若以id結尾,則接android.cursor.item/
        3.最後街上vnd.<authority>.<path>
        如下:
        */
        switch(uriMatcher.match(uri)){
              case TABLE1_DIR:
                //以路徑結尾
                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
                break;
            case TABLE1_ITEM:
                //以id結尾
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
                break;
            case TABLE2_DIR:
                //同理
                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
                break;
            case TABLE1_ITEM:
                //同理
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
                break;
        }
        
        return null;
    }
}

完整實現跨程式資料共享

public class MyProvider extends ContentProvider{
    
    public static final int TABLE1_DIR = 0;
    public static final int TABLE1_ITEM = 1;
    public static final int TABLE2_DIR = 2;
    public static final int TABLE1_ITEM = 3;
    
    //實現資料庫的幫助類
    private MyDatabaseHelper dbHelper;
    
    private static UriMatcher uriMatcher;
    
    static{
        uriMatcher = new UriMatcher(Uri.Matcher.NO_MATCH);
        //第一個引數為authority(一般為應用包名.provider)
        //第二個引數為path,即查詢的表
        //第三個引數為自定義碼
        uriMatcher.addUri("com.example.app.provider","table1",TABLE1_DIR);
        uriMatcher.addUri("com.example.app.provider","table1/#",TABLE1_ITEM);
        uriMatcher.addUri("com.example.app.provider","table2",TABLE2_DIR);
        uriMatcher.addUri("com.example.app.provider","table2/#",TABLE2_ITEM);
    }
    
    @Override
    public boolean OnCreate(){
        //建立或更新資料庫
        dbHelper = new MyDatabaseHelper(context,"dbName.db",null,1);
        return false;//返回true代表初始化成功,false則為失敗
    }
    
    @Override
    public Cursor query(Uri uri,String[] projection,String selection,
                        String[] selectionArgs,String sortOrder){
        //查詢資料庫
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch(uriMatcher.match(uri)){
            case TABLE1_DIR:
                curos = db.query("tableName",projection,selection,selectionArgs,
                                null,null,sortOrder);
                //查詢該表的全部資料
                break;
            case TABLE1_ITEM:
                //獲取查詢的id值
                String id = uri.getPathSegments().get(1);
                curos = db.query("tableName",projection,"id = ?",new String[]{id},
                                null,null,sortOrder);
                //查詢該表下的某條資料
                break;
            case TABLE2_DIR:
                //類上
                break;
            case TABLE1_ITEM:
                //類上
                break;
        }
        return cursor;
    }
    
    //插入操作與查詢操作類似
    @Override
    public Uri insert(Uri uri,ContentValues values){
        /*
        想內容提供器中插入一條資料
        uri:確定插入的表
        values:插入的資料
        
        新增成功後會返回表示該條新資料的uri
        */
        return null;
    }
    //更新操作與查詢操作類似
    @Override
    public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs){
        /*
        更新資料時呼叫該方法
        uri:同理
        values:新的資料
        selection、selectionArgs:更新的條件
        
        返回更新了的行數
        */
        return 0;
    }
    //與查詢操作類似
    @Override
    public int delete(Uri uri,String selection,String[] selectionArgs){
        /*
        刪除資料時呼叫
        uri:同理
        selection、selectionArgs:同理
        
        返回被刪除的行數
        */
        return 0;
    }
    
    @Override
    public String getType(Uri uri){
        /*
        呼叫該方法,是根據傳入的uri返回相應的MIME型別
        MIME字串主要由3部分組成:
        1.vnd開頭
        2.如果URI以路徑結尾,則後接android.cursor.dir/,
        若以id結尾,則接android.cursor.item/
        3.最後街上vnd.<authority>.<path>
        如下:
        */
        switch(uriMatcher.match(uri)){
              case TABLE1_DIR:
                //以路徑結尾
                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
                break;
            case TABLE1_ITEM:
                //以id結尾
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
                break;
            case TABLE2_DIR:
                //同理
                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
                break;
            case TABLE1_ITEM:
                //同理
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
                break;
        }
        
        return null;
    }
}

總體來說,內容提供器的具體操作,與資料庫的操作類似,個人認為,其只是封裝了資料庫的操作,只對傳入的路徑進行增刪改查操作,所以對其他路徑的資料不會產生影響,所以安全。