我要做 Android 之 数据持久化

简介: 在现在的时代,数据显得格外重要,不单单对于国家,对于个人和公司也同样如此。但是数据量是如此的大以至于怎么处理是个麻烦事。今天我们来看一看 Android 是怎么解决的。

在现在的时代,数据显得格外重要,不单单对于国家,对于个人和公司也同样如此。但是数据量是如此的大以至于怎么处理是个麻烦事。今天我们来看一看 Android 是怎么解决的。
在 Android 中存储数据主要有三种方式:

File 文件存储
SharedPreferences存储
SQLite数据库存储

在分别介绍之前,先要知道以上三种方法使得数据文件都默认存储在哪里,方便后续验证
1 File 文件存储
在 Android 中写入和读取文件的方法,和 Java 中实现 IO 的程序是一样的,Context 类中提供了 openFileInput() 和 openFileOutput() 方法来打开数据库里的文件 IO 流。
在布局中添加 EditText 实例,然后重写 onDestroy() 为了在活动销毁之前把输入的文本保存起来。主要是通过 openFileOutput() 方法将获取到的之存储到 data 的文件中。同时会获得一个 FileOutputStream 对象,在借助它构建出一个 OutputStramWriter 对象,接着在使用 OutputStreamWriter 构建出一个 BufferedWriter 对象,此时就可以把文本写入文件中了。

img_ae75ad56fae6d732191796f2a22c7954.png
02.png

关键部分代码:

FileOutputStream fileOutputStream = openFileOutput("data", Context.MODE_PRIVATE);
bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
bufferedWriter.write(text);

这里说明一下 openFileOutput() 的两个参数,第一个不用多说,是代表文件名。就是把数据存入哪里。第二个是文件的操作模式:


img_e77ef6159287c82ad5ad829f08ec80ea.jpe
03.png

这里推荐使用 private 或者直接写 0,两者意义相同。

(2)读取数据

在OnCreate()中用openFileInput()方法指定了要从文件data中读取数据,之后代码和写入是对应的非常好理解。


img_86780717e07d9b2d7e9307adc44b96b5.png
04.png

2.SharePreferences存储

SharePreferences是一种轻型的数据存储方式,常用来存储一些简单的配置信息,如int、string、boolean、float和 long。它的本质是基于XML文件存储key-value键值对数据。

实现 SharedPreference 存储的步骤如下:

(1)调用 getSharedPreferences() 方法获得 SharedPreferences 对象,提供两个参数,指定文件名称和操作模式。

(2)调用 SharedPreferences 对象的 edit() 方法获得 SharedPreferences.Editor 引用对象

(3)调用 Edit 接口的形如 putXXX() 方法以键值对的形式保存 XXX 类型的数据。

(4)调用 Edit 接口的 commit() 方法提交键值对

一定注意,不用 SharedPreferences 对象去存储或修改数据,而是通过 Editor 对象。但获取数据的时候需要调用 SharedPreferences 对象的 getXXX() 方法。


img_e638c7ea995748c58989204280ba4451.png
05.png

还有其他很多方法就需要大家自己去探索了,使用方法都一样,把类型换一下就 OK 。

3.SQLite数据库存储

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,在存储大量复杂的关系型数据的时可以使用,比前面学过的只适用于存储简单数据的两种存储方式要好很多。

(1)创建数据库

先学习一个类 SQLiteOpenHelper, 它是 SQLiteDatabase 的帮助类,用于管理数据库的创建和升级。SQLiteOpenHelper 的使用步骤:

第一:自定义帮助类并且继承 SQLiteOpenHelper,并且重写两个方法:onCreate()和 onUpgrade(),分别在这两个方法中去实现创建、升级数据库的逻辑。还需要一个构造方法,这里用含有四个参数的构造方法就可以。

第二步:创建数据库时,先实例化一个自定义的帮助类,并提供四个参数,含义是(上下文,数据库名,创建Cursor的工厂类,版本号)。
第三步:用帮助类对象的getReadableDatabase() 和getWritableDatabase()去创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库SQLiteDatabase。
第四步:之后就可以利用得到的数据库进行增删改查的操作了。

从自定义帮助类开始,并重写两个方法及构造函数。在这里用帮助类帮助创建一个student表,包含学生的学号、姓名、年龄和年级,对应的SQL语句就放在一个字符串常量里。特别要注意语句一定要准确,多个空格都会建表失败。在onCreate()方法里会返回一个SQLiteDatabase对象,接下来终于接触到SQLiteDatabase的第一个常用方法execSQL(),这个方法非常万能,它可接受和处理SQL语句,换句话说,后面将要学习的增删改查不仅可以用提供好的现成的辅助性方法,还可直接用原生SQL语句再调用execSQL()就够了,在后面的学习中只介绍前一种方法。这里就调用execSQL()去创建表并打印一行提示的Toast。


img_683f90a8766e533d0c97983f11b7b944.png
06.png

创建数据库的基本代码:


img_bdf63182686d2a540882d00b68e746ad.png
07.png

大家可以自己增加布局方式和按钮的点击监听事件。我这里只是直接实现,没有处理任何逻辑。

(2)增加数据

现在学习之前看到的ContentValues类,常用它put()方法以键值对的形式存储基本类型数据。在增和改会用到它,可以理解为键就是表中属性名,值就是表中数据。还常用方法clear()清空所有数据。

再来学习SQLiteDatabase用于增添数据的辅助性方法insert(),三个参数含义(被操作的表名,空值字段的名称,数据即ContentValues对象),第二个参数一般传入null。学会之后给student表插入两行记录吧,因为id这个属性设置了自增长所以可以不用管它:


img_fef09829b62ec99eed6b4016cac55fae.png
08.png

(3)删除数据

删除数据的辅助性方法是delete(),第一个参数还是表示表名,第二第三个参数用于约束删除某一行或几行的数据。比如需要删除student表中年龄大于17的记录:


img_e3e7cd074ee43a37cf1df52883014a60.png
09.png

(4)更改数据

update() 方法提供四个参数,(表名,ContentValues对象,约束,约束),之前都学过了!来试试给表里唯一的学生Lucy的年级更改为高三:


img_24befda49b913f8467af791b9d720fd7.png
10.png

(5)查询数据

查询方法quary()复杂一些,需要至少七个参数(table, columns, selection, selectionArgs, groupBy, having, orderBy),含义是:(表名,要查询出的列名,查询条件子句,对应于selection语句中占位符的值,要分组的列名,分组后过滤条件,排序方式)。其实也不用担心,多数情况下少数几个参数就能完成查询操作了。其他参数统统赋值为 null。

还没完,这个方法会返回一个Cursor,查询到的数据都会从它取出。Cursor常用方法:moveToFirst()将指针移动到结果集的第一行;getColumnIndex()获取某一列在表中对应位置的索引;get某某某()传入索引以获取相应位置的某种类型的数据;close()关闭指针。


img_01e49d9907216d6f7d3f851ce3f26082.png
11.png

(6)升级数据库

MyHelper里需要重写的第二个方法onUpdate()用于帮助数据库进行版本更新。比如此刻需要在数据库再添加一张表course,只要在update()写好创建course的操作,然后想办法让它被调用就好了。还记得在实例化帮助类是需要传入的第四个参数版本号吗?之前的传入的是1,只要传入一个比1大的数就可以让update()执行了。在下图代码里利用了oldVersion去判断旧版本号,如果是1就只需要再建course表,如果初次运行程序,就只会执行onCreate()方法然后两张表就一起建立了。这样做的好处是无论更新到第几代都不会影响之前的操作数据,也能保证当前版本是最新的。

修改代码如下


img_ff5b509e1a859f151dac08687c2e4c1b.png
12.png

还有


img_efb63487fe189dca2c681b82a8f3e814.png
13.png

还有 onUpgrade 方法


img_81cb4c3f06d015171976d2f4278392c2.png
14.png

在 Activity 中的操作变化


img_bdfb580ac5c1ef995e77fcdc0e7ac159.png
15.png

这里推荐 郭神 的 LitePal 数据库,链接https://github.com/LitePalFramework/LitePal
愿我们成为真实的自己。

目录
相关文章
|
4月前
|
消息中间件 网络协议 Java
Android 开发中实现数据传递:广播和Handler
Android 开发中实现数据传递:广播和Handler
50 1
|
1月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
3月前
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
81 2
|
4月前
|
数据库 Android开发
Android 通过升级SettingsProvider数据强制覆盖用户的设置项
Android 通过升级SettingsProvider数据强制覆盖用户的设置项 【5月更文挑战第7天】
116 5
|
4月前
|
JSON Android开发 数据格式
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
70 2
|
4月前
|
Java Linux API
统计android设备的网络数据使用量
统计android设备的网络数据使用量
99 0
|
1月前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
42 1
|
1月前
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
35 6
|
1月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
1月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。