美文网首页Android知识Android技术知识Android开发
Android开发:ContentProvider实例详解

Android开发:ContentProvider实例详解

作者: Gunther | 来源:发表于2016-12-13 14:58 被阅读757次
    • 2016年12月8日,Google中国开发者大会在京举行,同时正式上线了Google中国开发者网站Google Developers,查看官方学习资源再也不用爬梯子了
    1. 简介
    2. 使用说明
    3. ContentObserver

    简介

    ContentProvider即内容提供者,是Android的四大组件之一。内容提供者是应用程序之间共享数据的接口,Android系统将这种机制应用到方方面面。

    比如:联系人Provider专为不同应用程序提供联系人数据;设置Provider专为不同应用程序提供系统配置信息,包括内置的设置应用程序等。当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。

    虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用SharedPreferences共享数据,需要使用SharedPreferences API读写数据。

    而使用ContentProvider共享数据的好处是统一了数据访问方式。内容提供者将数据封装,只暴露出我们希望提供给其他程序的数据。内容提供者中数据更改可被监听。

    使用说明

    1. 定义类继承ContentProvider,根据需要重写内部方法(增删改查)
    2. 在清单文件的<application>节点下进行配置,<provider>标签中需要指定name和authorities属性
      name:类名,包名从程序Package开始,以“.”开始
      authorities:是访问Provider时的路径,要唯一
    3. URI代表要操作的数据,由scheme、authorites、path三部分组成
      content://cn.gunther.sqlite.provider/person
      scheme:固定为content,代表访问内容提供者
      authorites:<provider>节点中的authorites属性
      path:程序定义的路径,可根据业务逻辑定义

    示例代码:

    1. 新建一个工程MyContentProvider,包名:com.gunther.provider。
    2. 在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) {
    
        }
    
        }
    
    1. 在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数据发送变化,根据业务需求处理
        }
    }

    相关文章

      网友评论

        本文标题:Android开发:ContentProvider实例详解

        本文链接:https://www.haomeiwen.com/subject/zuqbmttx.html