Android系统编程入门系列之应用内键值对数据的简单保存
在应用程序间及与用户的通信交互过程中,会产生并传递一系列数据。针对这些数据,有部分是只在应用程序中使用的缓存数据,还有一部分是在不同位置多次或长时间使用的持久化数据。
对于缓存数据来说,通常以代码中定义局部变量或全局变量的方式访问使用,这种使用方式伴随在编程的整个过程中;而持久化数据,则需要以特定的文件格式保存在系统硬盘中,使用系统提供的框架方法来访问使用。而根据要持久化保存数据的复杂程度不同,分别有轻量级SharedPreferences,数据库SQLiteOpenHelper或其封装的Room,以及二进制访问的文件File这三种方式。本文主要对持久化数据的几种不同类型简做介绍。
轻量级SharedPreferences
对于轻量级的键值对数据,可以使用android.content.SharedPreferences共享选项接口实现的相关类以持久化保存。
以SharedPreferences形式保存的数据,将会以 key-value 键值对的形式,基于 xml 格式的文件保存在当前应用的内部存储空间中。这种应用程序的内部存储空间中的文件,只允许其所属应用程序读写。而当应用程序卸载后,或通过 系统桌面 - 设置 - 应用管理 - 当前应用程序 - 应用数据 - 清除数据 系列操作后,其内部存储空间也将被清空。这在一定程度上保证了内部存储空间的数据安全。
创建文件
在AndroidSDK中已经定义SharedPreferencesImpl类作为SharedPreferences接口的实现类。
对于SharedPreferences接口的实例化对象,在可以访问上下文环境Context对象的地方,可通过调用Context对象的getSharedPreferences(String name, int mode)方法获取。其对应的 xml 格式文件将在当前应用程序整个生命周期过程中读写访问。
或者也可以在Activity界面中,调用Activity对象的getPreferences(int mode)方法获取,其对应的 xml 文件只在当前界面生命周期中读写访问。
在getSharedPreferences(String name, int mode)方法中,
参数 name 指定存储当前数据的 xml 格式文件的文件名,其值可由开发者定义。
参数 mode 为文件的打开方式,其值通常为仅允许当前应用程序访问该文件的Context.MODE_PRIVATE=0;在Android6.0即API23之前,该值也可以为允许多进程读写同步的Context.MODE_MULTI_PROCESS=4,然而该模式下会出现各种异常问题,故此版本后被弃用;在Android4.2即API17之前,mode 值也可以为允许其他应用程序读该文件的Context.MODE_WORLD_READABLE=1,和允许其他应用程序写该文件的Context.MODE_WORLD_WRITEABLE=2,但这两个值均不能保证当前应用程序的数据安全性,故此版本之后被弃用。
另外,如果看不惯系统定义的SharedPreferencesImpl实现类,开发时完全可以自定义一个SharedPreferences接口的实现类,在使用context.getSharedPreferences(String name, int mode)获取实例化对象的位置替换为自定义的实现类对象即可。
总之,在获取SharedPreferences对象时,系统检测当前应用程序内部存储空间中是否有指定 name 的 xml 格式文件,若没有将会先创建。之后系统便会打开该文件,通过SharedPreferences对象就可以读写该文件了。
数据写入文件
如果想向创建的SharedPreferences对象所在文件中写入数据,只需要调用该对象的edit()方法,以获取android.content.SharedPreferences.Editor接口类型的对象。
类似于界面间交互使用的Intent意图中传递的数据方式,在SharedPreferences.Editor接口对象中,可以使用putBoolean(String key, boolean value)设置boolean类型的数据,putFloat(String key, float value)设置float类型的数据,putStringSet(String key, Set<String> values)设置String集合的数据等。这一系列的设置方法,其参数一 key 都是作为SharedPreferences文件中唯一的String类型的值,以标记当前数据;其参数二 value 则是要持久化保存的数据值。
另外,在SharedPreferences.Editor接口对象中,也可以使用remove (String key)方法以删除存在的参数 key 所标记的数据内容。或者直接使用clear()方法清空设置的所有数据内容。
在通过SharedPreferences.Editor接口对象设置或删除完数据后,调用其apply()或commit()方法以一次性提交设置的所有数据,在提交之后系统会将上文设置的数据都保存到SharedPreferences文件中。
虽然
commit()方法可以返回boolean值以判断是否提交成功,但并不推荐使用该方法;使用apply()方法可以更安全的保证提交的数据成功保存。
文件读取数据
如果想读取SharedPreferences对象所在文件的数据,就没有将数据写入文件那么繁琐的步骤了。只需要直接调用SharedPreferences对象的getBoolean(String key, boolean defValue)获取boolean类型的数据值,getFloat(String key, float defValue)获取float类型的数据值,getStringSet(String key, Set<String> defValues)获取Set<String>类型的数据值等。这一系列的获取方法,其参数一 key 与写入文件时的设置方法中的参数 key 一致,以标记响应数据;参数二 defaultValue 则是默认的数据值,当SharedPreferences文件中并没有保存参数 key 对应的数据时,将会返回 defaultValue 所设置的数值。
如果保存的数据量并不多,也可以直接调用SharedPreferences对象的getAll()方法,获取Map<String, ?>集合类型的所有数据,再对得到的数据分别操作处理。
另外SharedPreferences对象的contains(String key)方法,也可以只判断当前SharedPreferences对象所在文件中是否有参数 key 所标记的数据内容,返回boolean类型的结果。
文件修改的实时监听
可以用SharedPreferences对象的registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener)方法,实时监听当前SharedPreferences文件的修改操作。
参数 listener 是android.content.SharedPreferences.OnSharedPreferenceChangeListener接口的实例化对象,在该接口中实现了onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)方法。
一旦 listener 被注册,在参数 sharedPreferences 对应的文件中数据标记的 key 在被修改后, listener 中的onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)方法将会被系统回调。
对于已经注册的 listener ,尤其记得要在不需要监听之后,调用SharedPreferences对象的unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener),将之前注册的OnSharedPreferenceChangeListener对象撤销掉,以防止在后续出现内存泄漏的问题。
轻量级的SharedPreferences存储方式,可以很方便的存储一些简单数据,其内存效率是比较高的。然而如果应用程序中所有的数据都使用这种存储方式,反而使SharedPreferences文件的操作效率降低了,而且所有数据都使用这种键值对的形式存取,也会增加代码量。那么有什么更合适的存储方式适合不同类型的数据吗?详情请关注下一篇文章。
Android系统编程入门系列之应用内键值对数据的简单保存的更多相关文章
- Android系统编程入门系列之应用内数据保存数据库
上篇文章已经介绍了如何使用SharedPreferences存储键值对形式的轻量级数据,对于那些相同结构的多组数据,类似于存储Java中定义的类的多个对象属性值,如果按照键值对的形式一条条读写,需要分 ...
- Android系统编程入门系列之加载界面Activity
上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...
- Android系统编程入门系列之应用环境及开发环境介绍
作为移动端操作系统,目前最新的Android 11.0已经发展的比较完善了,现在也到了系统的整理一番的时间,接下来的系列文章将以Android开发者为中心,争取用归纳总结的态度对初级入门者所应 ...
- Android系统编程入门系列之硬件交互——多媒体摄像头
多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...
- Android系统编程入门系列之界面Activity绘制展示
上篇文章介绍了界面Activity的启动方式和生命周期,本篇将继续介绍在界面Activity中的内容是如何绘制展示给用户的. 在Android系统上运行新创建的界面Activtiy,给用户展示的是空白 ...
- Android系统编程入门系列之界面Activity交互响应
在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...
- Android系统编程入门系列之界面Activity响应丝滑的传统动画
上篇文章介绍了应用程序内对用户操作响应的相关方法位置,简单的响应逻辑可以是从一个界面Activity跳转到另一个界面Activity,也可以是某些视图View的相对变化.然而不管是启动一个界面执行新界 ...
- Android系统编程入门系列之界面Activity响应多元的属性动画
在响应丝滑动画一篇文章中,分别介绍了作用于普通视图.绘制视图的绘制对象.和界面这三种对象的动画效果,但是都有一些使用的局限性.比如这些动画都只是以屏幕上绘制更新的方式绘制动画,并没有真实改变作用对象的 ...
- Android系统编程入门系列之加载服务Service
之前几篇文章简单梳理了在Android系统的四大组件之一,最主要的界面Activity中,使应用程序与用户进行交互响应的相关知识点,那对于应用程序中不需要与用户交互的逻辑,又要用到哪些内容呢?本文开始 ...
随机推荐
- 第十四篇 -- CPU学习二——此部分重点在AMD CPU
一.CPU的一些英文简写或解释 Definitions: ACPI--Advanced Configuration and Power Interface APP--Adjusted Peak Per ...
- 谷粒商城--分布式高级篇P102~P128
谷粒商城--分布式高级篇P102~P128 由于学习的时间也比较少,只有周六周末才有时间出来学习总结,所以一篇一篇慢慢更新吧,本次总结内容为Elasticsearch(相关内容:kibana,es,n ...
- SQL之case when then用法_之二
select CustomerNo, Name, Sex, Birthday, IDType, IDNo, validityday, case (null ) when '1' then '高级VIP ...
- 原来select语句在MySQL中是这样执行的!看完又涨见识了!这回我要碾压面试官!
大家好,我是冰河~~ MySQL作为互联网行业使用最多的关系型数据库之一,与其免费.开源的特性是密不可分的.然而,很多小伙伴工作了很多年,只知道使用MySQL进行CRUD操作,这也导致很多小伙伴工作多 ...
- vulnhub-Lampiao脏牛提权
准备工作 在vulnhub官网下载lampiao靶机Lampião: 1 ~ VulnHub 导入到vmware,设置成NAT模式 打开kali准备进行渗透(ip:192.168.200.6) 信息收 ...
- 关于Asp.Net MVC html.renderaction传递参数
View视图 @{html.renderaction("控制器方法名","控制器名称",new{params1="参数值"})} Contr ...
- CTF之隐写总结
目测要更很久,因为今年有一件非常重要的事要完成,希望一切顺利 All The Best.
- Java 7 新特性之try-with-resources实践理解
想象这么一个情景,我们需要使用一个资源,在使用完之后需要关闭该资源,并且使用该资源的过程中有可能有异常抛出.此时我们都会想到用try-catch语句,在finally中关闭该资源.此时会有一个问题,如 ...
- Java面向对象04——构造器
类中的构造器也成为构造方法,是在进行创建对象的时候必须调用的.并且构造器有以下两个特点: 必须和类的名字相同 必须没有返回值,也不能写void package oop.demon01.demon02 ...
- Python爬虫学习——1.爬虫入门
HTTP和HTTPS HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfer ...