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

对于缓存数据来说,通常以代码中定义局部变量或全局变量的方式访问使用,这种使用方式伴随在编程的整个过程中;而持久化数据,则需要以特定的文件格式保存在系统硬盘中,使用系统提供的框架方法来访问使用。而根据要持久化保存数据的复杂程度不同,分别有轻量级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. odoo14学习----x2many操作与图片设置继承image.mixin

    三种方式实现数据更新 一,如上所述 二,通过对数据集调用update({'key':value,'key1':value1..})更新数据集 三,调用write函数,与update类似,传递字典.   ...

  2. HashSet 的实现原理

    HashSet 概述 对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素,所以如果对 HashMap 比较熟悉了,那么学习 HashSet 也是很轻松的 ...

  3. react native踩坑记录

    一 .安装 1.Python2 和Java SE Development Kit (JDK)可以直接通过腾讯电脑关键安装, Android SDK安装的时候路径里不能有中文和空格 2.配置java环境 ...

  4. java继承基础详解

    java继承基础详解 继承是一种由已存在的类型创建一个或多个子类的机制,即在现有类的基础上构建子类. 在java中使用关键字extends表示继承关系. 基本语法结构: 访问控制符 class 子类名 ...

  5. wireshark常见分析

    转载于https://www.cnblogs.com/sn1per/p/12553064.html https://www.cnblogs.com/csnd/p/12332421.html 直接看上面 ...

  6. java小游戏java九宫格

    问题来源于吾爱破解https://www.52pojie.cn/thread-1484202-1-1.html 编程目标一:根据下面的"游戏说明",实现该游戏程序,完成响应用户的输 ...

  7. Android开发三年,面了八家公司终于腾讯上岸,含泪整理面经

    在下2017年毕业,目前从事android开发工作已经3年多了,前段时间刚完成一次跳槽,面试了几家公司,将一些面试经验分享给大家,希望对大家有所帮助. 写在前面 这次跳槽总共是面了8家,(2小,4中, ...

  8. 【原创】利用动态二进制加密实现新型一句话木马之PHP篇

    概述 本系列文章重写了java..net.php三个版本的一句话木马,可以解析并执行客户端传递过来的加密二进制流,并实现了相应的客户端工具.从而一劳永逸的绕过WAF或者其他网络防火墙的检测. 本来是想 ...

  9. Linux+Apache+Mysql+PHP简单的测试环境搭建

    系统版本为:Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x ...

  10. SQL 练习22

    查询出只选修两门课程的学生学号和姓名 --方式1: SELECT Student.SId,Sname from Student WHERE SId in ( SELECT sid from sc GR ...