Android数据库基础

目录

1、安卓数据存储方式

2、数据库事务

数据库事务的特性(ACID)

事务的隔离级别

事务总结

3、ContetProvider

作用

​编辑

统一资源标识符URI

​编辑

MIME类型

ContentProvider主要方法

4、ContentResolver

作用

主要方法

使用案例

辅助工具类

ContentUris

UriMatcher

ContentObserver


1、安卓数据存储方式

  • SharedPreference
  • 文件存储
  • SQLite
  • 网络存储

2、数据库事务

数据库事务的特性(ACID)

  • 原子性:事务包含所有操作要么全部成功,要不回滚到原状态
  • 一致性:事务执行前后,数据库的状态保持一致
  • 隔离性:多用户并发访问数据库,多事务间相互不影响
  • 持久性:事务一旦被提交,则永久修改数据库的数据

事务的隔离级别

  • 读未提交
  • 读已提交:避免脏读(读到未提交数据)
  • 可重复度:避免不可重复读(当前事务而言,即使被另一个事务修改源数据,其看到的数据仍然是事务开始时刻的状态)
  • 串行化:避免幻读(一个事务已经开始并且读取了数据之后,另一个事务插入了新的记录,使得第一个事务在后续的操作中可能会看到之前未读到的新数据。)

事务总结

3、ContetProvider

作用

  • 原理底层是采用Binder机制
  • 为存储和获取数据提供统一接口,实现应用程序间数据共享
  • 通过URI可操作不同ContentProvider中数据
  • 外部进程可通过ContentResolver类与ContentProvider进行交互

  • 进程间数据交互与共享,实现跨进程通信
  • ContentProvider相当于搬运工,真正数据源还是数据库、文件、XML、网络

统一资源标识符URI

唯一标识ContentProvider中数据

MIME类型

指定某个扩展名文件用某种应用打开

MIME类型组成 = 类型+子类型

如:

  • text/html
  • text/xml
  • text/css
  • application/pdf

MIME类型形式

ContentProvider主要方法

//外部进程向ContentProvider中添加数据
fun insert(uri:Uri,contentValues values):Uri
//外部进程删除ContentProvider中数据
fun delete(uri:Uri,selection:String,selectionArgs:String[]):Int
//外部进程更新ContentProvider中数据
fun update(uri:Uri,values:ContentValues,selection:String,selectionArgs:String[]):int
//外部应用获取ContentProvider中数据
fun query (uri:Uri,projection:String[],selection:String,selectionArgs:String[],sortOrder:String):Cursor

4、ContentResolver

作用

通过 URI 即可操作不同 ContentProvider中数据

外部进程通过ContentResolver与ContentProvider进行交互

对所有的ContentProvider进行统一管理

主要方法

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

//外部进程向ContentProvider中添加数据
fun insert(uri:Uri,contentValues values):Uri
//外部进程删除ContentProvider中数据
fun delete(uri:Uri,selection:String,selectionArgs:String[]):Int
//外部进程更新ContentProvider中数据
fun update(uri:Uri,values:ContentValues,selection:String,selectionArgs:String[]):int
//外部应用获取ContentProvider中数据
fun query (uri:Uri,projection:String[],selection:String,selectionArgs:String[],sortOrder:String):Cursor

使用案例

val resolver = getContentResolver()
val uri = Uri.parse("content://cn.scu.myprovider/user")val cursor:Cursor = resolver.query(uri,null,null,null,"userid desc")

辅助工具类

ContentUris

向URI追加&获取ID

// withAppendedId()作用:向URI追加一个id
Uri uri = Uri.parse("content://cn.scu.myprovider/user") 
Uri resultUri = ContentUris.withAppendedId(uri, 7);  
// 最终生成后的Uri为:content://cn.scu.myprovider/user/7// parseId()作用:从URL中获取ID
Uri uri = Uri.parse("content://cn.scu.myprovider/user/7") 
long personid = ContentUris.parseId(uri); 
//获取的结果为:7

UriMatcher

在ContentProvider中注册URI,根据URI返回注册码,匹配ContentProvider中对应的数据表

// 步骤1:初始化UriMatcher对象UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //常量UriMatcher.NO_MATCH  = 不匹配任何路径的返回码// 即初始化时不匹配任何东西// 步骤2:在ContentProvider 中注册URI(addURI())int URI_CODE_a = 1;int URI_CODE_b = 2;matcher.addURI("cn.scu.myprovider", "user1", URI_CODE_a); matcher.addURI("cn.scu.myprovider", "user2", URI_CODE_b); // 若URI资源路径 = content://cn.scu.myprovider/user1 ,则返回注册码URI_CODE_a// 若URI资源路径 = content://cn.scu.myprovider/user2 ,则返回注册码URI_CODE_b// 步骤3:根据URI 匹配 URI_CODE,从而匹配ContentProvider中相应的资源(match())@Override   public String getType(Uri uri) {   Uri uri = Uri.parse(" content://cn.scu.myprovider/user1");   switch(matcher.match(uri)){   // 根据URI匹配的返回码是URI_CODE_a// 即matcher.match(uri) == URI_CODE_acase URI_CODE_a:   return tableNameUser1;   // 如果根据URI匹配的返回码是URI_CODE_a,则返回ContentProvider中的名为tableNameUser1的表case URI_CODE_b:   return tableNameUser2;// 如果根据URI匹配的返回码是URI_CODE_b,则返回ContentProvider中的名为tableNameUser2的表}   
}

ContentObserver

观察URI引起ContentProvider中的数据变化&通知访问者

// 步骤1:注册内容观察者ContentObservergetContentResolver().registerContentObserver(uri);// 通过ContentResolver类进行注册,并指定需要观察的URI// 步骤2:当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)public class UserContentProvider extends ContentProvider { public Uri insert(Uri uri, ContentValues values) { db.insert("user", "userid", values); getContext().getContentResolver().notifyChange(uri, null); // 通知访问者} 
}// 步骤3:解除观察者getContentResolver().unregisterContentObserver(uri);// 同样需要通过ContentResolver类进行解除

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

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

相关文章

BPMN.js学习

查看流程图 processView: {title: ,open: false,index: undefined,xmlData:"", },<el-table-column label"模型名称" align"center" :show-overflow-tooltip"true"><template slot-scope"scope"><el-button…

抖音短视频矩阵系统源码开发与部署全解析

1. 需求分析与功能规划 在着手开发短视频矩阵源码之初&#xff0c;首要任务是界定项目需求。这包含对视频上传、编辑、分享、评论及点赞等功能的实现预期。同时&#xff0c;需深入理解目标用户群体的具体需求和使用习惯&#xff0c;以确保产品能够满足市场需求。 2. 技术选型…

游戏如何应对黑灰产工作室

游戏黑灰产工作室&#xff0c;是指以非法渠道、非法手段通过游戏进行牟利的团伙。使用脚本、外挂是黑灰产工作室的显著特征&#xff0c;其常见的牟利方式有&#xff1a;打金工作室、资源囤积号、初始号、自抽号、代练工作室以及营销欺诈等。 ▲ 常见的游戏黑灰产工作室牟利路径…

视频太大怎么压缩变小?这几种压缩方法值得收藏!

视频太大怎么压缩变小&#xff1f;在数字化浪潮汹涌的时代&#xff0c;处理大型视频文件已不再仅仅是存储空间的挑战&#xff0c;我们身处于数据洪流之中&#xff0c;数据的安全与隐私的保护已然成为了我们不得不面对的重大议题&#xff0c;特别是随着视频内容的井喷式增长及其…

Qt学生管理系统(付源码)

Qt学生管理系统 一、前言1.1 项目介绍1.2 项目目标 2、需求说明2.1 功能性说明2.2 非功能性说明 三、UX设计3.1 登录界面3.2 学生数据展示3.3 信息插入和更新 三、架构说明3.1 客户端结构如下3.2 数据流程图3.2.1 数据管理3.2.2 管理员登录 四、 设计说明3.1 数据库设计3.2 结构…

智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成

日前&#xff0c;乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序&#xff0c;即可轻松设计符合 Matter 标准的产品。不仅如此&#xff0c;开发者还可以在短短…

算法模块导学

算法分析版本迭代流程图设计算法实践 练就扎实的基本功&#xff0c;可量化&#xff0c;可评估的&#xff0c;不是停留在大脑中的感觉。 1、算法&测开之缘 我们学习算法的目标是为了测试服务的&#xff0c;所以我们要了解测开最终要具备什么样的能力。 测开需要具备的能力…

从0开始的STM32HAL库学习4

对射式红外传感器计数复现 配置工程 我们直接复制oled的工程&#xff0c;但是要重命名。 将PB14设置为中断引脚 自定义命名为sensorcount 设置为上升沿触发 打开中断 配置NVCI 都为默认就可以了 修改代码 修改stm32f1xx_it.c 文件 找到中断函数并修改 void EXTI15_10_I…

Python精神病算法和自我认知异类数学模型

&#x1f3af;要点 &#x1f3af;空间不确定性和动态相互作用自我认知异类模型 | &#x1f3af;精神病神经元算法推理 | &#x1f3af;集体信念催化个人行动力数学模型 | &#x1f3af;物种基因进化关系网络算法 | &#x1f3af;电路噪声低功耗容错解码算法 &#x1f4dc;和-…

【Java】零散知识--感觉每条都有知识在进入脑子唤起回忆

1&#xff0c;什么是双亲委派 AppClassLoader在加载类时&#xff0c;会向上委派&#xff0c;取查找缓存。 AppClassLoader >>ExtClassLoader >>BootStrapClassLoader 情况一 向上委派时查找到了&#xff0c;直接返回。 情况二 当委派到顶层之后&#xff0c;缓…

CSS特效:pointer-events: none;的一种特殊应用

一、需求描述 今天看到一个设计需求&#xff1a;需要在弹框中显示如下界面&#xff0c;其中有两个效果&#xff1a; 1.顶部点击项目&#xff0c;下面的内容能相应滚动定位&#xff0c;同时滚动的时候顶部项目也能相应激活显示 2.顶部右侧有一个模糊渐变效果&#xff0c;并且要…

从0到1搭建数据中台(1)

初识 数据仓库&#xff0c;数据湖&#xff0c;大数据平台&#xff0c;数据中台的发展历程梳理&#xff1b;数据中台的搭建方法论&#xff1b;数据中台搭建的初步落地&#xff0c;参考大神郭忆的课程&#xff0c;看完就会对全貌有个理解。 Easydata大数据生产力平台架构图。 有…

vue实例和容器的一夫一制——04

//准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp2> <h1>{{name}}</h1> </div> <script> // 验…

久期分析与久期模型

目录 一、久期分析的理论原理 二、数据准备 三、Stata 程序代码及解释 四、代码运行结果 一、久期分析的理论原理 久期&#xff08;Duration&#xff09;是衡量债券价格对利率变动敏感性的重要指标。它不仅仅是一个简单的时间概念&#xff0c;更是反映了债券现金流回收的平均…

Elasticsearch:Node.js ECS 日志记录 - Pino

在我的上一篇文章 “Beats&#xff1a;使用 Filebeat 从 Python 应用程序中提取日志” 里&#xff0c;我详述了如何使用 Python 来生成日志&#xff0c;并使用 Filebeat 来收集日志到 Elasticsearch 中。在今天的文章中&#xff0c;我来详细描述如何使用 Node.js 来生成 ECS 相…

龙迅#LT6711GXE适用于HDMI2.1转DP1.4/TPYE-C应用方案,分辨率高达8K30HZ,4K144HZ!

1. 描述 LT6711GXE 是带有 PD 控制器的 HD-DVI2.1 到 DP1.4a 转换器。 对于 HD-DVI2.1 输入&#xff0c;LT6711GXE可以配置为 3/4 通道。自适应均衡使其适用于长电缆应用&#xff0c;最大带宽高达 40Gbps。它支持最高分辨率的8K30Hz、4K144Hz或8K60Hz压缩数据&#xff08;直通&…

小巧低调的黑盒子,打造个性化音乐体验,欧尼士ONIX Alpha小尾巴上手

欧尼士ONIX的产品很有辨识度&#xff0c;这家来自英国的品牌&#xff0c;有着鲜明的黑金设计色彩&#xff0c;以及低调奢华的质感&#xff0c;当然最重要的是&#xff0c;欧尼士的音质表现非常出色&#xff0c;因此深受音乐爱好者的喜爱。在以手机等设备为载体的流媒体音乐盛行…

旅游景区度假村展示型网站如何建设渠道品牌

景区、度假村、境外旅游几乎每天的人流量都非常高&#xff0c;还包括本地附近游等&#xff0c;对景区及度假村等固定高流量场所&#xff0c;品牌和客户赋能都是需要完善的&#xff0c;尤其是信息展示方面&#xff0c;旅游客户了解前往及查看信息等。 通过雨科平台建设景区度假…

前端预览图片的两种方式:转Base64预览或转本地blob的URL预览,并再重新转回去

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 预览图片 一般情况下&#xff0c;预览图片功能&#xff0c;是后端返回一个图片地址资源&#xff08;字符串&#xff09;给前端&#xff0c;如&#xff1a;ashuai.work/static…

springboot大学校园二手书交易APP-计算机毕业设计源码25753

摘 要 在数字化与移动互联网迅猛发展的今天&#xff0c;人们对于图书的需求与消费方式也在悄然改变。为了满足广大读者对图书的热爱与追求&#xff0c;我们倾力打造了一款基于Android平台的图书交易APP。这款APP不仅汇聚了海量的图书资源&#xff0c;提供了便捷的交易平台&…