在应用程序间及与用户的通信交互过程中,会产生并传递一系列数据。针对这些数据,有部分是只在应用程序中使用的缓存数据,还有一部分是在不同位置多次或长时间使用的持久化数据。

对于缓存数据来说,通常以代码中定义局部变量或全局变量的方式访问使用,这种使用方式伴随在编程的整个过程中;而持久化数据,则需要以特定的文件格式保存在系统硬盘中,使用系统提供的框架方法来访问使用。而根据要持久化保存数据的复杂程度不同,分别有轻量级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对象时,系统检测当前应用程序内部存储空间中是否有指定 namexml 格式文件,若没有将会先创建。之后系统便会打开该文件,通过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文件的修改操作。

参数 listenerandroid.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系统编程入门系列之应用内键值对数据的简单保存的更多相关文章

  1. Android系统编程入门系列之应用内数据保存数据库

    上篇文章已经介绍了如何使用SharedPreferences存储键值对形式的轻量级数据,对于那些相同结构的多组数据,类似于存储Java中定义的类的多个对象属性值,如果按照键值对的形式一条条读写,需要分 ...

  2. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  3. Android系统编程入门系列之应用环境及开发环境介绍

        作为移动端操作系统,目前最新的Android 11.0已经发展的比较完善了,现在也到了系统的整理一番的时间,接下来的系列文章将以Android开发者为中心,争取用归纳总结的态度对初级入门者所应 ...

  4. Android系统编程入门系列之硬件交互——多媒体摄像头

    多媒体系列硬件 多媒体包括图片.动画.音频.视频,这些多媒体素材的采集(输入)主要依靠摄像头和麦克风等硬件设备转化为基础数据,而他们的播放渲染(输出),则需要依靠具有相关功能的编解码软件.当然随着硬件 ...

  5. Android系统编程入门系列之界面Activity绘制展示

    上篇文章介绍了界面Activity的启动方式和生命周期,本篇将继续介绍在界面Activity中的内容是如何绘制展示给用户的. 在Android系统上运行新创建的界面Activtiy,给用户展示的是空白 ...

  6. Android系统编程入门系列之界面Activity交互响应

    在上篇文章中已经了解到界面Activity的绘制完全依赖其加载的视图组件View,不仅如此,用户的每次触摸操作都可以在界面Activity内接收并响应,也可以直接传递给其中的某个视图View响应.本文 ...

  7. Android系统编程入门系列之界面Activity响应丝滑的传统动画

    上篇文章介绍了应用程序内对用户操作响应的相关方法位置,简单的响应逻辑可以是从一个界面Activity跳转到另一个界面Activity,也可以是某些视图View的相对变化.然而不管是启动一个界面执行新界 ...

  8. Android系统编程入门系列之界面Activity响应多元的属性动画

    在响应丝滑动画一篇文章中,分别介绍了作用于普通视图.绘制视图的绘制对象.和界面这三种对象的动画效果,但是都有一些使用的局限性.比如这些动画都只是以屏幕上绘制更新的方式绘制动画,并没有真实改变作用对象的 ...

  9. Android系统编程入门系列之加载服务Service

    之前几篇文章简单梳理了在Android系统的四大组件之一,最主要的界面Activity中,使应用程序与用户进行交互响应的相关知识点,那对于应用程序中不需要与用户交互的逻辑,又要用到哪些内容呢?本文开始 ...

随机推荐

  1. 【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."

    API 管理 (APIM) 是一种为现有后端服务创建一致且现代化的 API 网关的方法. 问题描述 在设置了APIM客户端证书,用户保护后端API,让请求更安全. 但是,最近发现使用客户端证书的API ...

  2. (opencv09)cv2.getStructuringElement()构造卷积核

    (opencv09)cv2.getStructuringElement()构造卷积核 rectkernel = cv2.getStructuringElement(shape, ksize, anch ...

  3. Android内存溢出、内存泄漏常见案例及最佳实践总结

    内存溢出是Android开发中一个老大难的问题,相关的知识点比较繁杂,绝大部分的开发者都零零星星知道一些,但难以全面.本篇文档会尽量从广度和深度两个方面进行整理,帮助大家梳理这方面的知识点(基于Jav ...

  4. synchronized 优化手段之锁膨胀机制!

    synchronized 在 JDK 1.5 之前性能是比较低的,在那时我们通常会选择使用 Lock 来替代 synchronized.然而这个情况在 JDK 1.6 时就发生了改变,JDK 1.6 ...

  5. vue实现单点登录的N种方式

    最近项目停工了,RageFrame的学习暂时告一段落,这一篇给大家分享下有关单点登录的相关知识,并提供一些demo给大家参考,希望对想了解的朋友有一些帮助. 话不多说,先上原理(借鉴地址:https: ...

  6. Fast Run:提高 MegEngine 模型推理性能的神奇功能

    作者:王博文 | 旷视 MegEngine 架构师 一.背景 对于深度学习框架来说,网络的训练/推理时间是用户非常看中的.在实际生产条件下,用户设计的 NN 网络是千差万别,即使是同一类数学计算,参数 ...

  7. 手脱UPX壳的方法

    0X00    了解 upx UPX作为一款元老级PE加密壳,在以前的那个年代盛行,著名病毒[熊猫烧香]就是使用这款加密壳. 0X01    单步跟踪法 就是使用ollydbg加载程序后,按F8进行单 ...

  8. 攻防世界pwn高手区——pwn1

    攻防世界 -- pwn1 攻防世界的一道pwn题,也有一段时间没有做pwn了,找了一道栈题热身,发现还是有些生疏了. 题目流程 拖入IDA中,题目流程如图所示,当v0为1时,存在栈溢出漏洞.在gdb中 ...

  9. 时间-i春秋

    记一道跑脚本的题 进入页面拿到一段代码. <?php header("content-type:text/html;charset=utf-8"); '天下武功唯快不破'; ...

  10. 【动画消消乐|CSS】083.纯CSS实现卡通齿轮效果

    前言 Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出-   自我介绍 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计 ...