ContentProvider类的解析

一、ContentProvider类

1.作用:专门用于不同应用之间进行数据共享的方式。

二、实现方法

1.创建ContenteProvider类

步骤一:继承ContentProvider接口,重写接口的方法

/*其他方法都好理解*/
public class BookProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        return false;
    }

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

    @Nullable
    @Override
    /*返回一个Uri请求所对应的MIME类型,如果不关心可直接返回null*/
    public String getType(Uri uri) {
        return null;
    }

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

    @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;
    }
}
View Code

步骤二:在AndroidManifest.xml中注册

<provider
       android:authorities="com.chen.android.provider"
       android:name=".BookProvider"
       android:process=":provider">
</provider>

其中android:authorities是Provider的唯一标识,外界应用必须声明相应的权限才能进行操作。

2.应用访问该ContentProvider

protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Uri uri = Uri.parse("content://com.chen.android.provider");
      getContentResolver().query(uri,null,null,null,null);
}

content://com.chen.android.provider:唯一标识了BookProvider属性。

通过Activity的ContentProvider管理器,利用Uri指定ContentProvider,并调用指定方法。

注:方法的调用是在Binder线程中的,而不是在Activity的onCreate()方法中

3.创建数据库(辅助)

如何创建数据库:SQLite的使用 和 第一行代码的示例

注:创建了名为Book和User两个Table

public class DbOpenHelper extends SQLiteOpenHelper {
    private static final String DBNAME = "book_provider.db";
    public static final String BOOK_TABLE_NAME = "book";
    public static final String USER_TABLE_NAME = "user";
    
    private String CREATE_BOOK_TABLE = "create table if ont exists"+BOOK_TABLE_NAME+"(_id INTEGER PRIMARY KEY,name TEXT)";
    private String CREATE_USER_TABLE = "create table if not exists"+USER_TABLE_NAME
            +"(_id INTEGER PRIMARY KEY,"+"name TEXT)";
    public DbOpenHelper(Context context, int version) {
        super(context, DBNAME, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_USER_TABLE);
        db.execSQL(CREATE_BOOK_TABLE);        
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
View Code

4.利用ContentProvider访问其中一个Table

为了知道外界访问是哪一张表,需要定义单独的Uri和Uri_Code,让Uri和Uri_Code相连。

利用UriMatch的addURI方法将两者关联起来。

/*
*BookProvider类中
*/  

private static final String AUTHORY = "com.chen.android.provider";
    private static final int BOOK_URL_CODE = 0;
    private static final int USER_URL_CODE = 1;
    private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
   //稍后用到这个变量
private String tableName;
@Override public boolean onCreate() { //访问权限之后为访问Book的地址(content://com.chen.android.provider/book),如果对则返回BOOK_URL_CODE mUriMatcher.addURI(AUTHORY,"book",BOOK_URL_CODE);
     //同上 mUriMatcher.addURI(AUTHORY,
"user",USER_URL_CODE); return false; }

获取客户端要访问的Table

//步骤一:利用客户端的uri选择出table名
    public String getTableName(Uri uri){
        String tableName = null;
        switch (mUriMatcher.match(uri)){
            case BOOK_URL_CODE:
                tableName = DbOpenHelper.BOOK_TABLE_NAME;
                break;
            case USER_URL_CODE:
                tableName = DbOpenHelper.USER_TABLE_NAME;
            break;
        }
        return tableName;
   }
View Code
//步骤二:在ContentProvider中创建DbOpenHelper
private DbOpenHelper mDbOpenHelper;
private Context mContext;

 @Override
    public boolean onCreate() {
        ....
        mContext = getContext();
        mDbOpenHelper = new DbOpenHelper(mContext,1);
        return false;
   }   
View Code
//步骤三:利用ContentProvider的query()其他方法也是一样的形式
    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        table = getTableName(uri);
        return mDbOpenHelper.getWritableDatabase().query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
    }
View Code

客户端:将Uri uri = Uri.parse("content://com.chen.android.provider");

改写成Uri uri = Uri.parse("content://com.chen.android.provider/book"); 这样就可以访问BookTable了

注:update、insert、delete会引起源数据的改变,需要通过ContentProvider通知外界改变

5.ContentProvider通知外界数据改变(暂时不知道怎么用)

registerContentObserver:注册观察者

unRegisterContentObserver:取消观察者

notifyChanged:通知当前数据发生改变

原文地址:https://www.cnblogs.com/rookiechen/p/5356244.html