Android组件(一) ContentProvider

1.什么是ContentProvider

ContentProvider,即内容提供者,是Android四大组件之一。底层采用Android中的binder机制,以uri的形式在进程间进行搬运,传递数据&实现进程间通信。

2.URI

定义:Uniform Resource Identifier ,统一资源标识符
格式:

主题名标识符资源路径
URI=content://com.example.test/User/1
URI前缀,表示ContentProvider使用的协议由Android规定ContentProvider的唯一标识符,一般为完整的类名(包.类名)可以动态访问的资源路径,上述为数据库中User表里id为1的数据。

3.ContentProvider类

3.1 在AndroidManifest.xml注册

<provider
    android:authorities="com.example.test/User/1" // 指定URI
    android:name=".test" //指定类名
    android:exported="true"></provider>

属性exported指定是否对外暴露数据,只有为true时,其他应用才可以访问该应用的数据;

3.2 方法

public boolean onCreate() 

该方法在ContentProvider创建后或其他应用程序第一次访问ContentProvide时,被系统创建出来,并立即回调该onCreate方法

public Uri insert(Uri uri, ContentValues values)

根据URI,外部进程向ContentProvider传入values对应数据

 public int delete(Uri uri, String selection, String[] selectionArgs) 

根据URI,外部进程删除ContentProvider中selection条件匹配的数据

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

根据URI,外部进程更新ContentProvider中selection条件匹配的数据

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder) 

根据URI,外部进程获取ContentProvider中selection条件匹配的数据

query()方法参数对应sql部分描述
Uri urifrom table_name指定应用程序和表名
String[] projectionselect column1指定查询的表名
String selectionwhere column=value指定where的约束条件
String[] selectionArgs-为where中的占位符提供具体的值
String sortOrderorder by column1指定查询结果的排序方式

以上四种方法由外部进程调用,并运行在ContentProvider进程的Binder线程池中(不是主线程)若ContentProvider使用多个SQLite存储数据或使用内存存储数据,需要线程同步

public String getType(Uri uri)

返回当前 Url 所代表数据的MIME类型

3.3 MIME类型

定义:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet邮件扩充
格式:type/subtype
MIME的结构为类型+子类型,两个字符串中间用’/’分隔而成,不允许空格存在。

类型描述
text普通文件
image图片文件,不包括视频,但包括动态图片(GIF)
audio音频文件
video视频文件
applicable应用程序文件

4.ContentResolver类

4.1 ContentResolver作用

ContentProvider类并不会直接与外部进程交互,而是通过ContentResolver 类,ContentResolver用于统一管理不同 ContentProvider间的操作。

4.2 获取ContentResolver

使用ContentResolver前,需要先获取ContentResolver

通过调用Content的 getContentResolver() 方法获取 ContentResolver对象实例,获取对象后根据Uri对数据进行CRUD操作。

ContentResolver resolver =  getContentResolver(); 
Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
Cursor cursor = resolver.query(uri, null, null, null, null); 

4.3 方法

ContentResolver 类提供了与ContentProvider类相同名字的4个方法:

public Uri insert(Uri uri, ContentValues values)

根据URI,外部进程向ContentProvider传入values对应数据

 public int delete(Uri uri, String selection, String[] selectionArgs) 

根据URI,外部进程删除ContentProvider中selection条件匹配的数据

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

根据URI,外部进程更新ContentProvider中selection条件匹配的数据

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder) 

根据URI,外部进程获取ContentProvider中selection条件匹配的数据

5.辅助ContentProvide的工具类

5.1 ContentUris类

5.1.1 withAppendedId

作用:向URI追加一个id

Uri uri = Uri.parse("content://com.example.test/User") 
Uri resultUri = ContentUris.withAppendedId(uri, 3);  

最终生成后的Uri为:content://com.example.test/User/3

5.1.2 parseId

作用:从URL中获取ID

Uri uri = Uri.parse("content://com.example.test/User/3") 
long personid = ContentUris.parseId(uri); 

获取的结果为:3

5.2 UriMatcher类

该类主要是对传入的 Uri 进行匹配,向UriMatcher注册Uri,参数code 是该Uri对应的标识码,根据标识码匹配数据库。

5.2.1 初始化UriMatcher对象
    UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 
    // 初始化不匹配任何东西
5.2.2 在ContentProvider 中注册URI(addURI())
    int URI_CODE_a = 1;
    int URI_CODE_b = 2;
    matcher.addURI("com.example.test", "user1", URI_CODE_a); 
    matcher.addURI("com.example.test", "user2", URI_CODE_b); 
5.2.3 根据URI 匹配 URI_CODE,从而匹配ContentProvider中相应的资源(match())
@Override   
    public String getType(Uri uri) {   
      Uri uri = Uri.parse(" content://com.example.test/User1");   
      switch(matcher.match(uri)){   
      case URI_CODE_a:   
        return tableNameUser1;   
      case URI_CODE_b:   
        return tableNameUser2;
    }   
}

5.3 ContentObserver类

ContentObserver:内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。当ContentObserver所观察的Uri发生变化时,便会触发它。
观察特定URI的步骤如下:
(1)创建特定的ContentObserver子类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现
(2) 利用context.getContentResolover()获得ContentResolove对象,接着调用 registerContentObserver()方法去注册内容观察者

getContentResolver().registerContentObserver(uri);

(3) 由于ContentObserver的生命周期不同步于Activity和Service等,因此不需要时,需要手动的调用 unregisterContentObserver()去取消注册。

getContentResolver().unregisterContentObserver(uri);

Android组件(二)Intent
Android组件(三)Broadcast

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rpk712

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值