ContentProvider
ContentProvider 在Android中的作用是对外共享数据,也就是说可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据进行增删改查。
ContentProvider就是自定义增删改查接口并暴露出去,让别的应用访问自己的数据。ContentProvider就是按照一定规则访问内容提供者的数据。
ContentProvider对外共享数据步骤:
1.定义一个类 继承 ContentProvider
2.定义匹配规则 Uri
3.通过静态代码块添加匹配规则
4.在manifest.xml中配置contentProvider
Uri介绍
uri代表了要操作的数据
上面我们提到了Android提供内容的加Provider,那么在Android中怎么区分各个Provider
Uri作为唯一的标识来标识这个Provider
ContentProvider的scheme为:content://
Authority用于唯一标识这个ContenProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数,路径的构建应根据业务而定,如下:
要操作file表中id为10的记录,可以构建这样的路径:file/10
要操作file表中id为10的记录的name字段,路径:file/10/name
要操作file表中的所有记录,可以构建这样的路径:/file
当然要操作的数据可以是数据库,也可以是文件、xml或者网络等其他存储方式。
代码示例:
public class FileProvider extends ContentProvider {
private Context mContext;
private static final int QUEYSUCESS = 0;
private static final int INSERTSUCESS = 1;
//UriMatcher.NO_MATCH表示不匹配任何路径的返回码
private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private SQLiteDatabase mDb;
private String mTableName = DbOpenHelper.STUDENT_TABLE_NAME;
static{
//注册所有要匹配的uri
mUriMatcher.addURI("com.itcast.contentp.FileProvider", "query", QUEYSUCESS);
mUriMatcher.addURI("com.itcast.contentp.FileProvider", "insert", INSERTSUCESS);
}
//该方法在其它应用第一次访问它时才会被创建
@Override
public boolean onCreate() {
mContext = getContext();
mDb = new DbOpenHelper(mContext).getWritableDatabase();
return false;
}
/**
*public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
*projection : 这个参数告诉查询要返回的列(Column)即需要的字段,比如Contacts Provider提供了联系人的ID和联系人的NAME等内容.
*selection :查询where字句
*selectionArgs : 查询条件属性值
*sortOrder :结果排序
*/
@Override
public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,String arg4) {
if (mUriMatcher.match(uri)== QUEYSUCESS ) {//uri匹配后进行下面的操作
Cursor cursor = mDb.query(tableName, arg1, arg2, arg3, null, null, null);
getContext().getContentResolver().notifyChange(uri, null);
return cursor;
}else{
throw new IllegalArgumentException("match fail");
}
}
这里只给出部分代码。。。。。。
ContenResolver
使用ContentResoler调用ContentProvider提供的接口,对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用Activity提供的getContentResolver()方法来获取ContentResolver对象。ContentResolver类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri,ContentValues values)
public int delete(Uri uri,String selection,String[] seletionArgs)
public int update(Uri uri,ContentValues values,String seletion,String[] selectionArgs)
public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder)
1.对ContentProvider中的数据进行增删改查
直接看代码:
//uriQuery必须与要查询的ContentProvider中的要操作数据的uri保持一致(btw 这里只给了查询好插入的例子)
ContentValues values = new ContentValues();
Cursor cursor = getContentResolver().query(uriQuery, null, null, null, null);
int count = cursor.getCount(); //获取到一共有多少行
int contact_id = count + 1;
ContentValues nameValues = new ContentValues();
nameValues.put("name", name);
nameValues.put("mime_type", "vnd.android.cursor.item/name");
nameValues.put("contact_id", contact_id);
getContentResolver().insert(uriInsert, nameValues);
2.监听ContentProvider中数据的变化
在ContentProvider发生数据变化时调用getContentResolver.notifyChange(uri,null)来通知注册在此URI上的访问者。当数据发生变化时会调用ContentObserver的onChange()来进行一系列的后续操作~~~
如下:
public class MainActivity extends Activity {
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册
uri = Uri.parse("content://com.example.contentp.AccountProvider");
getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()))
}
}
监听到变化后调用onChange()来执行一系列操作
private class MyObserver extends ContentObserver {
Uri uri = Uri.parse("content://com.example.contentp.AccountProvider");
public MyObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
Cursor cursor = getContentResolver().query(uri, new String[]{"file","mime_type","date"}, null, null, null);
while(cursor.moveToNext()){
//执行一些操作
}
}
}
ContentProviderClient
与ContentResolver一样都是用来对ContentProvider中的数据进行添加、删除、修改和查询操作的
通过调用getContentPesolver().acquireContentProviderClient(activity)方法获取ContentProviderClient对象。
用法跟ContentResolver相似,不同点是ContentProviderClient对象必须在结束使用后,调用ContentProviderClient.release()来释放。这会使系统释放对应的ContentProvider对象。
对于相同ContentProvider的多次调用,推荐使用ContentProviderClient.
网友评论