ContentProvider类的解析
一、ContentProvider类
1.作用:专门用于不同应用之间进行数据共享的方式。
二、实现方法
1.创建ContenteProvider类
步骤一:继承ContentProvider接口,重写接口的方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*其他方法都好理解*/ 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; } }
步骤二:在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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) { } }
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//步骤一:利用客户端的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; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//步骤二:在ContentProvider中创建DbOpenHelper private DbOpenHelper mDbOpenHelper; private Context mContext; @Override public boolean onCreate() { .... mContext = getContext(); mDbOpenHelper = new DbOpenHelper(mContext,1); return false; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//步骤三:利用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); }
客户端:将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:通知当前数据发生改变