理论知识
ContentProvider 是 Android中用于数据共享的机制,主要是用于进程间(App之间)。
如何进行数据共享?
内容提供者 ContentProvider
提供数据,需要继承这个类,,并重写其中的增删改查方法。
继承 ContentProvider 类并重写增删改查、getType和 onCtreate方法,在新版的Android studio中新建一个ContentProvider会自动在 Mainifest中进行注册。
- URI Authorities:相当于标识,通常由包名+provider组成
- Exported:是否对外暴露
- Enabled:是否生效
ContentProvider 中的方法
- onCreate():该方法在ContentProvider创建后会被调用,当其他应用程序第一次访问ContentProvide时,该ContentProvider会被创建出来,并立即回调该onCreate方法
- getType(Uri uri), 返回 当前Uri所代表的数据的MIME类型。如果该Uri对应数据可能包括多条记录,那么MIME类型字符串应该以 vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么返回MIME类型字符串应该以vnd.android.cursor.item/开头。
内容观察者 ContentObserver
观察ContentProvider提供的数据,并通知 ContentResolver
内容接收者 ContentResolver
- 处理数据,可以调用其类似数据库操作的增删改查方法,实现数据获取。
- 它提供的方法与ContentProvider一一对应。
- 但不同于sqlite数据库,它接收的不是表名而是一个url,这样可以保证数据的安全性。
什么是URI?
UriMatcher
UriMatcher本质是一个文本过滤器,可以直接得到Uri的path,可以通过调用uriMatcher.addURI()方法添加相对应的返回码
private UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
@Overridepublic boolean onCreate() {dataBaseHelper = new DataBaseHelper(getContext());sqLiteDatabase = dataBaseHelper.getWritableDatabase();uriMatcher.addURI(AUTHORITIES, DataBaseHelper.STUTDY_SQLITE_TABLE, 0);return true;}
@Overridepublic String getType(Uri uri) {int code = uriMatcher.match(uri);if (code == 0) {return DataBaseHelper.STUTDY_SQLITE_TABLE;} else {return null;}}
实战演练
App-A ContentProvider
package com.example.androidstudiostudy.contentprovider;import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;import com.example.androidstudiostudy.database.DataBaseHelper;public class MyContentProvider extends ContentProvider {private UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);private String AUTHORITIES = "com.example.androidstudiostydy.provider";private DataBaseHelper dataBaseHelper;private SQLiteDatabase sqLiteDatabase;public MyContentProvider() {}@Overridepublic boolean onCreate() {dataBaseHelper = new DataBaseHelper(getContext());sqLiteDatabase = dataBaseHelper.getWritableDatabase();uriMatcher.addURI(AUTHORITIES, DataBaseHelper.STUTDY_SQLITE_TABLE, 0);return true;}@Overridepublic String getType(Uri uri) {int code = uriMatcher.match(uri);if (code == 0) {return DataBaseHelper.STUTDY_SQLITE_TABLE;} else {return null;}}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {String tableName = getType(uri);if (tableName == null) {return null;}return sqLiteDatabase.query(tableName, projection, selection, selectionArgs, null, null, sortOrder);}/// 删除@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {String tableName = getType(uri);// 查询的表不存在if (tableName == null) {return -1;}return sqLiteDatabase.delete(tableName, selection, selectionArgs);}/// 更新@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {String tableName = getType(uri);// 查询的表不存在if (tableName == null) {return -1;}return sqLiteDatabase.update(tableName, values, selection, selectionArgs);}@Overridepublic Uri insert(Uri uri, ContentValues values) {String tableName = getType(uri);// 查询的表不存在if (tableName == null) {return null;}long index = sqLiteDatabase.insert(tableName, null, values);if (index > 0) {return uri;} else {return null;}}}
App-B ContentResolver
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getContentProviderData();}// 接收来自其他app的数据public void getContentProviderData() {ContentResolver contentResolver = getContentResolver();Uri uri = Uri.parse("content://com.example.androidstudiostydy.provider/STUTDY_SQLITE_TABLE");@SuppressLint("Recycle")// 检查 Cursor 是否为空Cursor cursor = contentResolver.query(uri, null, null, null, null);if (cursor != null) {while(cursor.moveToNext()){int id = cursor.getInt(0);String name = cursor.getString(1);String phone = cursor.getString(2);String pwd = cursor.getString(3);Log.d("contentprovider", id + "\t" + name + "\t" + phone + "\t" + pwd);}cursor.close();} else {Toast.makeText(this, "无法获取内容提供者数据", Toast.LENGTH_LONG).show();}}