ContentProvider 内容提供者 暴露数据
ContentResolver 内容解析者 操作数据的
ContentObserver 内容观察者 观察数据的变化
内容提供者:
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。目前,使用内容提供器是android实现跨程序共享数据的标准方式。
内容提供者可以把私有的数据库暴露出来。
内容提供者把数据进行封装然后提供出来,其他应用都是通过内容解析者(Content Resolver)来访问。
案例:{应用程序MonitorData,应用程序ContentObserverDb}
操作数据库
public class PersonDBOpenHelper extends SQLiteOpenHelper {
//构造方法,调用该方法创建一个person.db数据库
public PersonDBOpenHelper(Context context) {
super(context, "person.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建该数据库的同时新建一个info表,表中有_id,name这两个字段
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
创建内容提供者类
public class PersonProvider extends ContentProvider {
//定义一个uri路径的匹配器,如果路径匹配不成功返回-1
private static UriMatcher mUriMatcher = new UriMatcher(-1);
private static final int SUCCESS = 1; //匹配路径成功时的返回码
private PersonDBOpenHelper helper; //数据库操作类的对象
//添加路径匹配器的规则
static {
mUriMatcher.addURI("com.example.contentobserverdb", "info", SUCCESS);
}
@Override
public boolean onCreate() { //当内容提供者被创建时调用
helper = new PersonDBOpenHelper(getContext());
return false;
}
/**
* 查询数据操作
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//匹配查询的Uri路径
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
return db.query("info", projection, selection, selectionArgs,
null, null, sortOrder);
} else {
throw new IllegalArgumentException("路径不正确,无法查询数据!");
}
}
/**
* 添加数据操作
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
long rowId = db.insert("info", null, values);
if (rowId > 0) {
Uri insertedUri = ContentUris.withAppendedId(uri, rowId);
//提示数据库的内容变化了
getContext().getContentResolver().notifyChange(insertedUri, null);
return insertedUri;
}
db.close();
return uri;
} else {
throw new IllegalArgumentException("路径不正确,无法插入数据!");
}
}
/**
* 删除数据操作
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.delete("info", selection, selectionArgs);
//提示数据库的内容变化了
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
db.close();
return count;
} else {
throw new IllegalArgumentException("路径不正确,无法随便删除数据!");
}
}
/**
* 更新数据操作
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.update("info", values, selection, selectionArgs);
//提示数据库的内容变化了
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
db.close();
return count;
} else {
throw new IllegalArgumentException("路径不正确,无法更新数据!");
}
}
@Override
public String getType(Uri uri) {
return null;
}
}
在主类中执行操作
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ContentResolver resolver;
private Uri uri;
private ContentValues values;
private Button btnInsert;
private Button btnUpdate;
private Button btnDelete;
private Button btnSelect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); //初始化界面
createDB(); //创建数据库
}
private void initView() {
btnInsert = findViewById(R.id.btn_insert);
btnUpdate = findViewById(R.id.btn_update);
btnDelete = findViewById(R.id.btn_delete);
btnSelect = findViewById(R.id.btn_select);
btnInsert.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
btnDelete.setOnClickListener(this);
btnSelect.setOnClickListener(this);
}
private void createDB() {
//创建数据库并向info表中添加3条数据
PersonDBOpenHelper helper = new PersonDBOpenHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();
for (int i = 0; i < 3; i++) {
ContentValues values = new ContentValues();
values.put("name", "itcast" + i);
db.insert("info", null, values);
}
db.close();
}
@Override
public void onClick(View v) {
//得到一个内容提供者的解析对象
resolver = getContentResolver();
//获取一个Uri路径
uri = Uri.parse("content://com.example.contentobserverdb/info");
//新建一个ContentValues对象,该对象以key-values的形式来添加数据到数据库表中
values = new ContentValues();
switch (v.getId()) {
case R.id.btn_insert:
Random random = new Random();
values.put("name", "add_itcast" + random.nextInt(10));
resolver.insert(uri, values);
Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
Log.i("数据库应用", "添加");
break;
case R.id.btn_delete:
int deleteCount = resolver.delete(uri, "name=?", new String[]{"itcast0"});
Toast.makeText(this, "成功删除了" + deleteCount + "行", Toast.LENGTH_SHORT).show();
Log.i("数据库应用", "删除");
break;
case R.id.btn_select:
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
//返回查询结果,是一个指向结果集的游标
Cursor cursor = resolver.query(uri, new String[]{"_id", "name"},
null, null, null);
//遍历结果集中的数据,将每一条遍历的结果存储在一个List的集合中
while (cursor.moveToNext()) {
Map<String, String> map = new HashMap<String, String>();
map.put("_id", cursor.getString(0));
map.put("name", cursor.getString(1));
data.add(map);
}
//关闭游标,释放资源
cursor.close();
Log.i("数据库应用", "查询结果:" + data.toString());
break;
case R.id.btn_update:
//将数据库info表中name为itcast1的这条记录更改为name是update_itcast
values.put("name", "update_itcast");
int updateCount = resolver.update(uri, values, "name=?", new String[]{"itcast1"});
Toast.makeText(this, "成功更新了" + updateCount + "行", Toast.LENGTH_SHORT).show();
Log.i("数据库应用", "更新");
break;
}
}
}
观察者:观察数据库操作
// 用来检测数据变化
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 该uri路径指向数据库应用中的数据库info表
Uri uri = Uri.parse("content://com.example.contentobserverdb/info");
//注册内容观察者,参数uri指向要监测的数据库info表,
//参数true定义了监测的范围,最后一个参数是一个内容观察者对象
getContentResolver().registerContentObserver(uri, true,
new MyObserver(new Handler()));
}
private class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {//handler 是一个消息处理器。
super(handler);
}
@Override
//当info表中的数据发生变化时则执行该方法
public void onChange(boolean selfChange) {
Log.i("监测数据变化", "有人动了你的数据库!");
super.onChange(selfChange);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册内容观察者
getContentResolver().unregisterContentObserver(new MyObserver(
new Handler()));
}
}