ContentProvider基础知识

news2024/12/24 2:17:25

ContentProvider基础知识

1.ContentProvider入门

1.简介

  • 不同程序之间的数据交换,不同app之间的数据共享
  • 学会如何操作数据
  • 学会如何监听数据变化
  • 学会URI,URImatcher,ContentUris的如何使用

2.基本使用

  • A应用,使用ContentProvider的子类进行暴漏数据(前面的五种数据存储的方式),同时给出一个Uri地址
  • B应用,使用ContentReserver进行数据的接收

总之URI是数据连接的桥梁。

3.ContentProvider的简介

  • 四大组件之一
  • 存储和获取数据提供URI接口地址
  • 可以共享数据
  • 系统中常用的视频音频以及电话和短信都有相应的操作
  • 使用的是非execSQL的方式执行查询
  • 一种数据就是一个ContentProvider

4.ContentProvider组织数据的方式

  • 以表的形式组织数据
  • 联系人,通话信息,短信信息,一行就是一条记录
  • _ID是唯一的

5.ContentProvider的使用

  • 自定义,详见1.1.7
  • 系统的

6.ContentProvider方法

抽象类,需要重写它的onCreate()、delete()、getType()、insert()、query()、update()这几个抽象方法。

  • boolean onCreate(),创建后被调用,第一次访问的时候调用
  • insert的用法:Uri insert(Uri uri, ContentValues values),根据Uri插入values中的数据
  • query的用法:select projections from 表 where selection=selectionArgs order by sortOrder
  • delete的用法:public int delete(Uri uri, String selection, String[] selectionArgs),该方法根据Uri删除where条件匹配的所有记录。
  • update的用法:int update(Uri uri, ContentValues values, String selection, String[] selectionArgs),该方法根据Uri修改where条件匹配的全部记录。
  • String getType(Uri uri),返回当前Uri所代表数据的MIME类型。就是一种用来定义除了基本数据类型外的其他类型的数据的一种方法

方法名称

功能描述

public boolean onCreate()

创建ContentProvider时调用

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

根据传入的Uri删除指定条件下的数据

public Uri insert(Uri uri,ContentValues values)

根据传入的Uri插入数据

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

根据传入的Uri查询指定条件下的数据

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

根据传入的Uri更新指定条件下的数据

public String getType(Uri uri)

用于返回指定Uri代表的MIME类型

注意:在增删改查方法里可以使用嵌入式SQL语句,但是就不如直接使用SQLiteDatabase的增删改查方法直接简单了。

7.ContentProvider主要方法

  • 操作集合:MIME需要以vnd.android.cursor.dir/开头。
  • 操作非集合:如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
案例1
例如,假设一个provider含有列车时刻表,provider的authority是com.example.trains,并且它包含三个表:路线1,路线2,路线3。在URI的响应中,
content://com.example.trains/Line1。指向路线1表,provider返回对应的MIME类型为:
vnd.android.cursor.dir/vnd.example.line1
而content URI:content://com.example.trains/Line2/5。指向路线2表的第5,provider返回的对应的MIME类型为:
vnd.android.cursor.item/vnd.example.line2
案例2
假设一个provider有人员表,该provider的authority是cn.itcast.provider.personprovider。包含一个表:person。
例如:要得到Uri为content://cn.itcast.provider.personprovider/person指向表person,代表所有person记录,那么provider对应的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。
例如:得到id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。

2.自定义的ContentProvider

1.实现过程

  1. 数据源创建就是SQLite的帮助类和实体类等
  2. 自定义类ContentProvider,增删改查+getType以及onCreate方法
  3. 定义URI常量提供ContentResover可以访问到的ContentProvider
  4. 注册,privder标签
<provider
	android:name=cn.itcast.db.PersonDBProvider
	android:authorities=cn.itcast.db.personprovider
              android:exported="true">
</provider>
<!--属性依次为:全限定类名,用于匹配的URI,是否共享数据 -->

3.系统的的ContentProvider

后续补充

4.URI

1.简介:

  • 统一资源定位符,Universal Resource Identifier的简称
  • 每一个ContentProvider都拥有一个公共的URI,这个URI用于表示ContentProvider提供的数据

在AndroidManifest.xml中ContentProvider提供了一个uri的authority部分作为数据的统一接口,就是android:authoritiesContentResolver通过该uri(即Content_URI)访问ContentProvider

2.URL介绍

  • URL是WWW统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
  • http://youke.baidu.com/course/1

3.URI组成

  • 协议://URI标识(注册文件的authority定义的)/路径/ID

  • 实例:
    • content://com.example.codelab.transportationprovider/train:要操作train数据资源所有的记录(如train表)
    • content://com.example.codelab.transportationprovider/train/10:要操作train数据资源中id为10的记录(如train表中id为10的记录)
    • content://com.example.codelab.transportationprovider/train/10/name:要操作train数据资源中id为10的记录的name字段
    • content://com.example.codelab.transportationprovider/train/international:要操作train表下的子表international
    • content://media/external:这个Uri将返回设备上存储的所有图片;
    • content://media/external/images/media/4:某个图片的Uri
    • content://contacts/people:这个Uri将返回设备上的所有联系人信息;

注意:当然要操作的数据不一定来自数据库,也可以是文件等存储方式,如下:

要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name

3.方法

  • parse(str),将str转换成URI地址
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/2")
 Uri uri=Uri.parse("content://com.lxz.app6/studnet/2");
  • List<String> getPathSegments(),获取uri的path,部分存入List

5.解析URI

1.解析URI的

  • 因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。
  • UriMatcher和ContentUris用于解析Uri

2.UriMatcher

  • 用于匹配Uri地址,UriMatcher可以检验当前的Uri地址是不是合法的,合法才可以使用
  • 检验原理:对一个URI的规则起一个编号,如果URI符合这个规则,则返回这个编号,如果在UriMatcher里找不到这个规则,则没有这个编号。规则是int值
  • 使用步骤
    • 初始化UriMatcher
    • 设置需要的URI规则
    • 与已经注册的Uri进行匹配

3.使用UriMatcher步骤

  1. 初始化
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//常量UriMatcher.NO_MATCH表示Uri不匹配时的返回码
  1. 设置需要匹配的Uri规则。

方法名

描述

public void addURI (String authority, String path, int code)

添加一个用于匹配Uri的规则,当匹配成功时则给该Uri一个intcode(匹配码)

public int match (Uri uri)

uri进行匹配

uriMatcher.addURI("com.lxz.app6","studnet",1);
uriMatcher.match(uri);
扩展:
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//添加需要匹配uri(content://cn.itcast.provider.personprovider/person),如果匹配成功就会给该Uri一个匹配码1
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为数字通配符,用了匹配任何数字,*匹配任何字符

匹配码的值需要大于0,否则抛出IllegalArgument异常

  1. 使用match匹配返回匹配ma
switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) { 
   case 1:。。。。。。
    break;
   case 2:。。。。。。。
    break;
   default://不匹配
    break;
}

4.ContentUris类简介

  • ContentUris类用于操作Uri路径后面的ID部分。该类下的方法都为静态方法。
  • 它有两个比较实用的方法:
    • public static Uri withAppendedId (Uri contentUri, long id):用于为路径加上ID部分。
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10); 
//生成后的Uri为:content://cn.itcast.provider.personprovider/person/10

    • public static long parseId (Uri contentUri),该方法用于从路径中获取ID
(id是指数据库中每条记录的唯一标识,即id号。)
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10

6.ContentResover

1.简介

  • 当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成
  • 获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。
  • ContentResolver 类提供了与ContentProvider类相同签名的四个方法,这些方法分别会调用ContenProvider中与之对应的方法,并得到返回的结果。只管调用不管实现。这些方法的第一个参数为Uri,代表要调用的ContentProvider)
假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”)
那么将会对uri为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。

2.使用ContentResover操作数据步骤

  1. 获取ContentResover,ContentResolver resolver = getContentResolver();
  2. 获取ContentProvider的URI标识,

Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");

  1. 使用ContentResolver进行增删改查操作,例如add操作
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
resolver.insert(uri, values);

  1. 监听ContentProvider中数据的变化
  • 在 android 中经常会出现改变数据库内容后再去使用数据库更新的内容,很多人会重新去 query 一遍,但是这样的问题就是程序会特别占内存,而且有可能会忘关 cursor 而导致程序内存未释放等等。
  • 如果应用程序需要实时监听ContentProvider共享的数据是否发生变化,并随着ContentProvider的数据的改变而提供响应。
  • CUD操作都会导致数据的变化,
getContext().getContentResolver().notifyChange(uri,null);
这行代码可用于通知所有注册在该Uri上的监听者:该ContentProvider所共享的数据发生了改变。

3.如何创建监听者,如何往Uri上加监听呢?

  • 内容观察者(ContentObserver)来实现。
  • 内容观察者(ContentObserver)是用来观察指定Uri所代表的数据变化,从而做一些相应的处理,类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。

4.创建监听的步骤

第12步“:


private final class SmsObserver extends ContentObserver{
	public SmsObserver(Handler handler) {
		super(handler);	
	}
	public void onChange(boolean selfChange) {
		Cursor cursor = getContentResolver().query(Uri.parse("content://sms/"),null, null, null, null); 
		while(cursor.moveToNext()){
			StringBuilder sb = new StringBuilder();			sb.append("_id=").append(cursor.getInt(cursor.getColumnIndex("_id")));		sb.append(",address=").append(cursor.getString(cursor.getColumnIndex("address")));	sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));		
            } }}

第3步:ContentProvider通知

public class PersonContentProvider extends ContentProvider {
	public Uri insert(Uri uri, ContentValues values) {
		db.insert("person", "personid", values);
		getContext().getContentResolver().notifyChange(uri, null);
	}
}

第4步:注册监听,第三个参数就是我们创建的监听器

例:
//注册监听
getContentResolver().registerContentObserver(Uri.parse("content://sms"),
        		true,
//true表示只要发出通知的Uri以方法第一个参数开头都能被监听到,否则监听uri必须与发出通知的uri完全匹配才能被监听到
                                           new PersonObserver(new Handler()));
//监听类
public class PersonObserver extends ContentObserver{
	public PersonObserver(Handler handler) {
		super(handler);
 	}
	public void onChange(boolean selfChange) {
	    //此处可以进行相应的业务处理
	}
}

5.取消注册

public final void unregisterContentObserver(ContentObserver observer)
功能:取消对给定Uri的观察

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/114080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ 第二天 高级 8 RabbitMQ 应用问题

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第二天 高级8 RabbitMQ 应用问题8.1 消息可靠性保障8.1.1 消息补偿8.2 消息幂等性保障8.2.1 乐观锁机制第二天 高级 8 RabbitMQ 应用问题 8.1 消息可靠性保障 在RabbitMQ的使…

pytorch【线性回归】【逻辑回归】【softmax回归】

文章目录零、前置函数线性相乘均方误差损失函数梯度下降函数数据的生成函数一、线性回归1.手动实现线性回归2.调库实现线性回归1.定义我们线性回归的模型2.定义我们的误差函数3.定义优化方法4.模型的训练5.开始训练6.查看模型的参数7.计算我们模型的当前的均方误差二、逻辑回归…

【5G RLC】AM模式的数据传输详解

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

Linux内核死锁检测工具——Lockdep

文章目录前言配置内核简单的AB-BA死锁案例实际项目中的死锁前言 死锁是指两个或多个进程因争夺资源而造成的互相等待的现象&#xff0c;如进程A需要资源X&#xff0c;进程B需要资源Y&#xff0c;而双方都掌握对方所需要的资源&#xff0c;且都不释放&#xff0c;这会导致死锁。…

【圣诞快乐】如何用代码画一颗圣诞树?

文章目录一、前言二、创意角度三、java swing版 效果展示四、java swing版 实现步骤&代码五、springboot项目banner版 效果展示六、springboot项目banner版 实现步骤七、 linux shell界面打印版 效果展示八、 linux shell界面打印版 实现步骤一、前言 一年一度的圣诞节来了…

Allegro如何设置差分对内等长规则

Allegro如何设置差分对内等长规则 Allegro上可以对差分网络设置对内等长规则,方便把P/N网络进行等长处理,以下面这对USB为例 具体操作如下 打开Constraint Manage找到这对USB网络

vue3 antd table表格的样式修改(一)调整table表格每行(row)行高过高问题

vue3 antd项目实战——修改ant design vue table组件的默认样式&#xff08;调整每行行高&#xff09;知识调用场景复现实际操作解决a-table表格padding过宽知识调用 文章中可能会用到的知识链接vue3ant design vuets实战【ant-design-vue组件库引入】css样式穿透&#xff08;…

RV1126笔记十三:实现RTMP多路拉流

若该文为原创文章,转载请注明原文出处。 一、介绍 通过RV1126实现RTMP的多路拉流,并在屏幕上显示出来,这里涉及到ffmpeg几个重要知识点,和RV1126如何在屏幕分屏显示。 二、流程图 流程和单路拉流类似,这里只是涉及拉取后的图像需要解码缩放,在合成分屏显示出来。 具体…

【完整】分类模型中类别不均衡问题解决

目录 1. 数据类别不均衡问题 2. 解决办法 过采样&#xff1a; 欠采样&#xff1a; ensemble 方法&#xff1a; 修改损失函数&#xff1a; 梯度调和机制&#xff1a; Dice Loss&#xff1a; 标签平滑&#xff1a; 3. 类别不均衡问题loss设计 4. 梯度调和机制GHM Gradi…

Graphviz安装向导

目录 1、首先在官网下载graphviz 2、安装。 3、测试 1、首先在官网下载graphviz 下载网址&#xff1a;Download | Graphviz 根据自身电脑位数选择合适的下载地址 2、安装。 打开第一步已经下载好的软件。点击下一步&#xff0c;在安装路径选择时可将安装路径修改为 E:\G…

JavaScript:栈的封装及十进制转二进制栈方法实现案例

栈的定义&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。 JavaScript中对栈的封装 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&qu…

微信HOOK 协议接口 实战开发篇 2.好友列表与二叉树

前言&#xff1a;由于篇幅所限&#xff0c;文章无法详细到每个步骤&#xff0c;仅能写出关键的HOOK思路 好友列表 好友和群列表在汇编代码中有固定的常量保存 如图示&#xff0c;找到常量&#xff0c;回车进入 入口地址结构为 其指针内部便是我们需要的数据 群列表 搜索Ch…

Linux中的进程状态

目录 一、冯诺伊曼体系结构​编辑 关于冯诺依曼&#xff0c;必须强调几点&#xff1a; 二、操作系统 1、概念 2、操作系统的作用 3、本质 4、总结 5、系统调用和库函数概念 三、进程 1、基本概念 2、描述进程 3、task_struct 4、查看进程 5、通过系统调用获取进程…

第19章 随机变量

第19章 随机变量 19.1随机变量示例 定义19.1.1&#xff1a;概率空间上的随机变量R是域等于样本空间的全函数。 R的陪域可以是任何东西&#xff0c;但通常是实数的一个子集。 例&#xff1a; 例如&#xff0c;假设我们抛三个独立的、公平的硬币。令C表示正面朝上的次数。如…

js中的JSON的简单用法

目录 1.JSON说明 2.JSON.stringify 3.JSON.parse 4.示例 1.JSON说明 当数据在浏览器与服务器之间进行交换时&#xff0c;这些数据只能是文本&#xff0c;JSON 属于文本并且我们能够把任何 JavaScript 对象转换为 JSON&#xff0c;然后将 JSON 发送到服务器。我们也能把从服…

最强docker部署模板

00.背景 最近学校让一个小组做一个web项目最后部署到linux服务器上&#xff0c;项目本身并不难就是简单的增删改查&#xff0c;但是我想借着这个机会写一个docker部署的模板&#xff0c;方便自己以后用&#xff0c;也希望可以帮助到大家。 01.docker简介 docker可以快捷 轻量…

Redis原理篇—网络模型

Redis原理篇—网络模型 笔记整理自 b站_黑马程序员Redis入门到实战教程 用户空间和内核态空间 服务器大多都采用 Linux 系统&#xff0c;这里我们以 Linux 为例来讲解: ubuntu 和 Centos 都是 Linux 的发行版&#xff0c;发行版可以看成对 Linux 包了一层壳&#xff0c;任何 …

第八章:数据库编程

一、嵌入式、过程化SQL、存储过程和函数 1、【单选题】 下表为oracle数据库表cj.temp_20221106的数据。建立存储过程: CREATE OR REPLACE PROCEDURE proc_temp_20221106(i INT) IS CURSOR c_temp IS SELECT * FROM cj.temp_20221106; ROW_NR c_temp%ROWTYPE; i_count …

【Linux】基础IO——系统文件IOfd重定向理解

文章目录一、回顾C文件接口1.打开和关闭2.读写文件3.细节二、系统文件I/O 1.open和closeumask小细节2.read和write1.write2.read3.小总结三、理解文件四、文件描述符fd1.引入2.理解3.分配规则4.close(1)问题五、重定向1.重定向2.接口3.追加重定向4.输入重定向六、Linux一切皆文…

信息技术 定义内涵

工作流运行 定义内涵 工作流运行是工作流模板的依次执行&#xff0c;在工作流运行时&#xff0c;用户可以随时取消或查看正在 运行的任务。由于工作流运行的模板的不同&#xff0c;运行过程中可能会产生不同的新资源&#xff0c;如数据 处理类型的工作流会产生新的数据集&…