ContentProvider

参考 https://blog.youkuaiyun.com/u012858833/article/details/51629245

ContentProvider管理android以结构化方式存放的数据。他以相对安全的方式封装数据并且提供简易的处理机制。Content provider提供不同进程间数据交互的标准化接口。

ContentProvider是允许不同应用进行数据交换的标准的API,ContentProvider以Uri的形式对外提供数据的访问操作接口,而其他应用则通过ContentResolver根据Uri去访问指定的数据。

一旦某个应用通过ContentProvider暴露了自己的数据接口,那么不管该应用程序是否启动,其他程序都可以通过该接口来操作自己的数据接口来操作其内部的数据,包括增加数据,删除数据,修改数据,查询数据等.

URI是统一资源标识符,是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作。URI由包括确定语法和相关协议的方案所定义。由是三个组成部分:访问资源的命名机制、存放资源的主机名、资源自身的名称,由路径表示。

比如:content://edu.android.demos/t_apps 中:

  • content:// 使用的是content协议,属于默认规定
  • edu.android.demos属于自己定义的主机名,唯一标识并区分不同的ContentProvider继承类
  • t_apps资源部分,当访问不同的资源的时候,这部分会动态改变

ContentProvider的使用离不开Uri类的支持,在自己的继承类中使用UriMatcher,根据UriMatcher.match(Uri uri)返回的表示符,进行不同范围,不同数据集的操作。

一旦定义好自己的ContentProvider类,就可以使用ContentResolver进行访问操作了。 ContentResolver类的方法都会在其内部调用URI主机部分确定的ContentProvider

监听ContentProvider相关的数据变化(ContentObserver类)

使用ContentObserver可以监测某一数据项的变化,当其中的内容发生变化是会自动调用其中的 public void onChange(boolean selfChange) {}方法。 比如可以监听手机中的短信变化,在变化后进行处理

1、请介绍下 ContentProvider 是如何实现数据共享的
在 Android 中如果想将自己应用的数据(一般多为数据库中的数据)提供给第三发应用,那么我们只能通过 ContentProvider 来实现了。
ContentProvider 是应用程序之间共享数据的接口。使用的时候首先自定义一个类继承ContentProvider,然后覆写 query、insert、update、delete 等方法。因为其是四大组件之一因此必须在 AndroidManifest 文件中进行注册。把自己的数据通过 uri 的形式共享出去。android 系统下,不同程序 数据默认是不能共享访问。需要去实现一个类去继承 ContentProvider
public class PersonContentProvider extends ContentProvider{
public boolean onCreate(){

}
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])
}
<provider
android:exported="true"
android:name="com.itheima.contenProvider.provider.PersonContentPro
vider"android:authorities="com.itheima.person" />
第三方可以通过 ContentResolver 来访问该 Provider。

2、说说 ContentProvider、ContentResolver、ContentObserver 之间的关系
a. ContentProvider 内容提供者,用于对外提供数据
b. ContentResolver.notifyChange(uri)发出消息
c. ContentResolver 内容解析者,用于获取内容提供者提供的数据
d. ContentObserver 内容监听器,可以监听数据的改变状态

e. ContentResolver.registerContentObserver()监听消息

3、为什么要用 ContentProvider?它和 sql 的实现上有什么差别?
ContentProvider 屏蔽了数据存储的细节,内部实现对用户完全透明,用户只需要关心操作数据的uri 就可以了,ContentProvider 可以实现不同 app 之间共享。
Sql 也有增删改查的方法,但是 sql 只能查询本应用下的数据库。而 ContentProvider 还可以去增删改查本地文件. xml 文件的读取等。
 

<think>好的,用户想了解Android开发中ContentProvider的用法和示例。首先,我需要回顾ContentProvider的基本概念,它是Android四大组件之一,主要用于不同应用间的数据共享。接着,要说明它的核心作用,比如封装数据访问、提供统一接口等。 然后,用户可能需要知道如何创建自定义的ContentProvider。这包括继承ContentProvider类,实现必要的方法如query、insert、update、delete等。还需要提到在AndroidManifest.xml中注册Provider,并设置android:exported属性来控制是否对外暴露。引用中的内容提到android:exported=false可以限制仅供内部使用,这点很重要,特别是涉及安全性的问题,必须包含进去。 接下来,应该给出一个简单的示例代码,展示如何定义ContentProvider的子类,并实现各个方法。同时,示例中的UriMatcher和SQLiteOpenHelper的使用也是关键点,需要解释清楚。代码部分要注意使用正确的格式,并确保语法正确。 另外,用户可能关心ContentProvider的使用场景,比如数据共享、与CursorLoader结合使用等。还要提到ContentResolver的用法,因为这是访问Provider的主要方式。需要强调线程安全,引用中提到5.4节关于线程安全的内容,应该指出在实现时需要注意同步机制,避免多线程问题。 最后,生成相关问题时要围绕用户可能进一步想知道的内容,比如如何限制访问权限、与数据库交互的细节、性能优化等。确保问题覆盖常见的使用场景和潜在的问题点,帮助用户深入理解。 现在需要检查回答是否符合系统指令,比如行内公式是否正确使用(虽然这里可能用不上,但要注意其他格式要求),独立公式是否单独成段,中文回答,以及引用标识是否正确添加。同时,确保示例代码正确,并且引用的内容自然插入到回答中,比如在讲解注册Provider时引用[^2],在讲解线程安全时引用[^1]等。 总结步骤:介绍ContentProvider的作用,创建步骤,示例代码,使用场景,安全配置,线程安全,最后生成相关问题。确保每个部分都清晰,并且引用正确。</think>### ContentProvider在Android开发中的使用及示例 ContentProvider是Android四大组件之一,主要用于**跨应用数据共享**,提供标准化的数据访问接口。以下是其核心知识点: #### 一、核心作用 1. **数据封装**:将数据源(如SQLite、文件、网络)封装为统一的访问接口。 2. **跨进程通信**:通过URI标识数据路径,支持其他应用通过ContentResolver访问数据。 3. **权限控制**:通过AndroidManifest.xml定义读写权限,例如: ```xml <provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:exported="false" <!-- 禁止外部访问 --> android:readPermission="android.permission.READ_DATA" android:writePermission="android.permission.WRITE_DATA"/> ``` 通过`android:exported=false`可限制仅供内部使用[^1]。 #### 二、自定义ContentProvider步骤 1. **继承ContentProvider类**并实现六个核心方法: ```java public class MyProvider extends ContentProvider { @Override public boolean onCreate() { // 初始化数据库等操作 return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询数据逻辑 } // 实现insert、update、delete、getType方法 } ``` 2. **定义数据URI**: ```java private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { uriMatcher.addURI("com.example.provider", "books", 1); // 匹配路径:/books } ``` #### 三、数据访问示例 通过ContentResolver操作数据: ```java // 查询数据 Cursor cursor = getContentResolver().query( Uri.parse("content://com.example.provider/books"), null, null, null, null ); // 插入数据 ContentValues values = new ContentValues(); values.put("title", "Android Guide"); getContentResolver().insert(uri, values); ``` #### 四、线程安全与性能 1. **线程安全**:ContentProvider方法默认运行在主线程,需自行实现同步机制(如使用`synchronized`块)。 2. **数据库优化**:建议配合SQLiteOpenHelper管理数据库连接,避免频繁打开关闭。 #### 五、典型应用场景 1. 应用内多个模块共享同一数据库 2. 向系统提供数据(如自定义联系人存储) 3. 与SyncAdapter配合实现后台数据同步
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值