- 2016年12月8日,Google中国开发者大会在京举行,同时正式上线了Google中国开发者网站Google Developers,查看官方学习资源再也不用爬梯子了
- 简介
- 使用说明
- ContentObserver
简介
ContentProvider即内容提供者,是Android的四大组件之一。内容提供者是应用程序之间共享数据的接口,Android系统将这种机制应用到方方面面。
比如:联系人Provider专为不同应用程序提供联系人数据;设置Provider专为不同应用程序提供系统配置信息,包括内置的设置应用程序等。当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。
虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用SharedPreferences共享数据,需要使用SharedPreferences API读写数据。
而使用ContentProvider共享数据的好处是统一了数据访问方式。内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据。内容提供者中数据更改可被监听。
使用说明
- 定义类继承ContentProvider,根据需要重写内部方法(增删改查)
- 在清单文件的<application>节点下进行配置,<provider>标签中需要指定name和authorities属性
name:类名,包名从程序Package开始,以“.”开始
authorities:是访问Provider时的路径,要唯一 - URI代表要操作的数据,由scheme、authorites、path三部分组成
content://cn.gunther.sqlite.provider/person
scheme:固定为content,代表访问内容提供者
authorites:<provider>节点中的authorites属性
path:程序定义的路径,可根据业务逻辑定义
示例代码:
- 新建一个工程MyContentProvider,包名:com.gunther.provider。
- 在com.gunther.provider.dao包下新建PersonOpenHelper类继承SQLiteOpenHelper类,该类用于创建数据库。
public class PersonOpenHelper extends SQLiteOpenHelper {
public PersonOpenHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
public PersonOpenHelper(Context context){
super(context, "person.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table person (id integer primary key autoincrement,name varchar(20),phone varchar(20),age integer,address varchar(50));";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
-
在com.gunther.contenProvider.provider包中创建,PersonContentProvider类继承ContentProvider类。同时将该Provider在AndroidManifest.xml中注册。
<provider android:exported="true" android:name="com.gunther.contenProvider.provider.PersonContentProvider" android:authorities="com.gunther.person" /> public class PersonContentProvider extends ContentProvider { //用于存放并匹配个Uri标识信息,一般在静态代码块中对其信息进行初始化操作 private static UriMatcher matcher; //声明一个用于操作数据库对象 private PersonOpenHelper openHelper; //主机名信息:对应清单文件的authorities属性 private static final String AUTHORITY = "com.gunther.person"; //数据库 表名 private static final String TABLE_PERSON_NAME = "person"; //Uri匹配成功的返回码 private static final int PERSON_INSERT_CODE = 1000; private static final int PERSON_DELETE_CODE = 10001; private static final int PERSON_UPDATE_CODE = 10002; private static final int PERSON_QUERYALL_CODE = 10003; private static final int PERSON_QUERYONE_CODE = 10004; //静态代码块,用于初始化UriMatcher static{ //NO_MATCH:没有Uri匹配的时候返回的状态码(-1) matcher = new UriMatcher(UriMatcher.NO_MATCH); //添加一个分机号: //对person表进行添加操作,如果Uri=content://com.gunther.person/person/insert,则返回PERSON_INSERT_CODE matcher.addURI(AUTHORITY, "person/insert", PERSON_INSERT_CODE); //对person表进行删除操作,如果Uri= content://com.gunther.person/person/delete,则返回PERSON_DELETE_CODE matcher.addURI(AUTHORITY, "person/delete", PERSON_DELETE_CODE); //对person表进行修改操作,如果Uri= content://com.gunther.person/person/update,则返回PERSON_UPDATE_CODE matcher.addURI(AUTHORITY, "person/update", PERSON_UPDATE_CODE); //对person表进行查询所有操作,如果Uri= content://com.gunther.person/person,则返回PERSON_QUERYALL_CODE matcher.addURI(AUTHORITY, "person", PERSON_QUERYALL_CODE); //对person表进行查询单个操作,如果Uri= content://com.gunther.person/person/#,(#:代表数字)则返回PERSON_QUERYONE_CODE matcher.addURI(AUTHORITY, "person/#", PERSON_QUERYONE_CODE); } @Override public boolean onCreate() { //内容提供者中,获取contenxt,是通过getContext,与测试类一样,不能再成员变量,构造函数中调用,但是可以再onCreate方法中获取。 openHelper = new PersonOpenHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { //用匹配器去匹配uri,如果匹配成功则返回匹配器中对应的状态码 int matchCode = matcher.match(uri); SQLiteDatabase db = openHelper.getReadableDatabase(); switch (matchCode) { case PERSON_QUERYALL_CODE: return db.query(TABLE_PERSON_NAME, projection, selection, selectionArgs, null, null, sortOrder); case PERSON_QUERYONE_CODE: //使用ContentUris工具类解析出uri中的id long parseId = ContentUris.parseId(uri); return db.query(TABLE_PERSON_NAME, projection,"id=?", new String[]{parseId+""}, null, null, sortOrder); default: throw new IllegalArgumentException("Uri匹配失败:"+uri); }} @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = openHelper.getWritableDatabase(); //新插入对象的id long id = db.insert(TABLE_PERSON_NAME, null, values); db.close(); //使用ContentUris工具类将id追加到uri中,返回给客户 return ContentUris.withAppendedId(uri, id); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = openHelper.getWritableDatabase(); //返回删除的个数 int count = db.delete(TABLE_PERSON_NAME, selection, selectionArgs); //关闭数据库 db.close(); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = openHelper.getWritableDatabase(); //返回更新的个数 int count = db.update(TABLE_PERSON_NAME, values, selection, selectionArgs); //更新数据库 db.close(); return count; } @Override public String getType(Uri uri) { return null; } }
ContentObserver
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。
private class AppLockObserver extends ContentObserver{
public AppLockObserver(){
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//观察到注册的uri数据发送变化,根据业务需求处理
}
}
网友评论