[技术博客] 利用SharedPreferences来实现登录状态的记忆功能

一、SharedPreferences简介

SharedPreferences是Android平台上一个轻量级的存储辅助类,用来保存应用的一些常用配置,它提供了string,set,int,long,float,boolean六种数据类型。最终数据是以xml形式进行存储。在应用中通常做一些简单数据的持久化缓存。

二、为什么要使用SharedPreferences?

首先我们要理解一下我们的程序是怎么工作的。我们的博客园APP需要不断地调用API从博客园官方数据库中获取数据,有些数据是每个用户独有的,有些数据是大家都能看的,这就导致每次请求数据时必须有一个身份认定来保护隐私。因此在用户登录后,我们会拿到一个Authorization_Code,它可以唯一标识一个用户。因此Authorization_Code是调用用户数据的关键,那么在我们的app中有5个模块,4个模块要用到Authorization_Code,只要有一个模块取得了Authorization_Code,必须通知到其它模块,不要再让用户登录了。这就需要我们用到单例模式来存储有关登录状态的信息。我们知道,虽然单例模式每次运行程序后只有一个实例,但是一旦我们退出程序重启,这个单例实例就会被重新创建,登录状态信息丢失,导致每次用户重新进入app后都要重新登录,造成了很大的不便。为了改善这一点,我们决定使用SharedPreferences来存储信息。

三、SharedPreferences存储机制

简单来说,SharedPreferences本质上使用的是文件存储,存储位置在/data/data/<程序包名>/shared_prefs/文件名.xml。在第一次创建这个文件后,只要用户不清理缓存,这个文件会一直存在。

四、简单示例

如何存储数据

public class Save extends AppCompatActivity {//这是一个activity
private SharedPreferences sharedpreferences;
private SharedPreferences.Editor editor;
private String code = "Example";//要存储的数据
@Override
protected void onCreate(Bundle savedInstanceState) {//重写activity的onCreate方法
super.onCreate(savedInstanceState);
setContentView(R.layout.save_activity);
sharedpreferences = getApplication().getSharedPreferences("User", Context.MODE_PRIVATE);//"User"是存储的文件名,Context.MODE_PRIVATE表示该文件只能被创建他的应用访问
editor = sharedpreferences.edit();
editor.putString("Code",code);//第一个参数相当于一个Key,后面取出数据时需要用到这个值来索引
editor.commit();
}
}

如何读取存储的数据

public class Read extends AppCompatActivity {//这是一个activity
private SharedPreferences sharedpreferences;
private String code;//要读取的数据
@Override
protected void onCreate(Bundle savedInstanceState) {//重写activity的onCreate方法
super.onCreate(savedInstanceState);
setContentView(R.layout.save_activity);
sharedpreferences = getApplication().getSharedPreferences("User", Context.MODE_PRIVATE);//"User"是存储的文件名,Context.MODE_PRIVATE表示该文件只能被创建他的应用访问,必须与存储时写的格式一样,否则会找不到文件
code = sharedpreferences.getString("Code","");//"Code"相当于Map中的Key,第二个参数""表示在没找到相应的数据时返回的值(默认值,可以用来判断其他地方是否导入过数据)
}
}

五、注意事项

虽然SharedPreferences使用方便,功能也比较实用,但是SharedPreferences有一些性能缺陷。

1、加载缓慢。

SharedPreferences 文件的加载使用了异步线程,而且加载线程并没有设置优先级,如果这个时候读取数据就需要等待文件加载线程的结束。这就导致主线程等待低优先线程锁的问题,比如一个 100KB 的 SP 文件读取等待时间大约需要 50 ~ 100ms。

2、跨进程不安全

由于没有使用跨进程的锁,就算使用 MODE_MULTI_PROCESS,SharedPreferences 在跨进程频繁读写有可能导致数据全部丢失。根据线上统计,SharedPreferences 大约会有万分之一的损坏率。

3、造成程序卡顿。

由于提供了异步落盘的 apply 机制,在崩溃或者其它一些异常情况可能会导致数据丢失。所以当应用收到系统广播,或者被调用onPause等一些时机,系统会强制把所有的SharedPreferences对象的数据落地到磁盘。如果没有落地完成,这时候主线程会被一直阻塞。这样非常容易造成卡顿,甚至是ANR,从线上数据来看 SP 卡顿占比一般会超过5%。

所以建议大家在使用时尽量少用,只用SharedPreferences来存储少量数据

[技术博客] 利用SharedPreferences来实现登录状态的记忆功能的更多相关文章

  1. [技术博客] 利用Vagrant+virtualbox在windows下进行linux开发

    目录 加速box安装的方法 root账户登录 换源教程 安装rvm 访问rails server RubyMine连接虚拟机上的解释器 作者:庄廓然 在windows下进行linux开发:利用Vagr ...

  2. [技术博客]利用第三方框架react-native-swipeout实现左右滑动出现按钮

    在之前的开发中,为了实现用户不同手势操作能够对应不同的功能,我们考虑使用React-Native的API--PanResponder,实现识别用户的手势,实现不同的功能.但我们很快就发现,这样简单的实 ...

  3. [技术博客]WEB实现划词右键操作

    [技术博客]WEB实现划词右键操作 一.功能解释 简单地对题目中描述的功能进行解释:在浏览器中,通过拖动鼠标选中一个词(或一段文字),右键弹出菜单,且菜单为自定义菜单,而非浏览器本身的菜单.类似的功能 ...

  4. 技术人如何利用 github+Jekyll ,搭建一个独立免费的技术博客

    上次有人留言说,技术博客是程序员的标配,但据我所知绝大部分技术同学到现在仍然没有自己的技术博客.原因有很多,有的是懒的写,有的是怕写不好,还有的是一直想憋个大招,幻想做到完美再发出来,结果一直胎死腹中 ...

  5. 【技术博客】利用handler实现线程之间的消息传递

    [技术博客]利用handler实现线程之间的消息传递 一.handler简介 在Android Studio的开发中,经常需要启动多个线程.比如向远程发送请求时,必须新开一个子线程,否则会造成程序崩溃 ...

  6. 【技术博客】JWT的认证机制Django项目中应用

    开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. JWT的认证机制Django项目中应用 这篇技术博客基于软 ...

  7. 【技术博客】忘记密码界面的Vue前端实现

    一.基本流程 [登录界面] --> [点击忘记密码] --> [输入个人邮箱和验证码] --> [系统发送邮箱验证] --> [用户在限定时间内登录邮箱,查收验证码] --&g ...

  8. 创建GitHub技术博客

    创建GitHub技术博客全攻略 githubio技术博客网站生成 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字.本 ...

  9. 在Ubuntu14.04上安装WordPress4搭建技术博客

    1.安装LAMP环境 1.1 安装Apache2 1.2 安装MySQL5 1.3 安装PHP5 1.4 安装phpMyAdmin 2.初始化数据库 3.下载并配置WordPress 4.配置Apac ...

随机推荐

  1. Mysql常用sql语句(4)- distinct 去重数据

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 我们使用select进行数据查询时是会返回所有匹 ...

  2. app自动化定位:UIautomation的用法

    UIautomation定位的优点: 速度比xpath定位快,UIautomation是Android的工作引擎 缺点: 没有idea提示 UIautomation使用方法: AndroidDrive ...

  3. "指针"和"引用"大对比

    相同点: 都能够直接引用对象,并对对象进行操作. 不同点: 指针 引用 指针类型的变量能够保存一个对象的地址 引用是一个对象的别名 可以为空nil,可以不初始化 不可以为空nil,必须初始化 当设计一 ...

  4. 简单操作:10分钟实现在kubernetes(k8s)里面部署服务器集群并访问项目(docker三)

    前言 经过docker安装.k8s开启并登录,我们终于到 "部署k8s服务器集群并访问项目" 这一步了,实现的过程中有太多坑,好在都填平了,普天同庆. 在进行当前课题之前,我们需要 ...

  5. 网络前置任务(Pretext task)和下游任务(downstream tasks)

    Pretext task 可以理解为是一种为达到特定训练任务而设计的间接任务. 比如,要训练一个网络来对 ImageNet 分类,可以表达为 $f_{\theta}(x): x \rightarrow ...

  6. RE Validation in JavaEE

    以下是关于RE校验的一些方法的基本功能: import java.util.regex.Pattern;<br> /** * 校验器:利用正则表达式校验邮箱.手机号等 * */<br ...

  7. 2. Go并发编程--GMP调度

    目录 1. 前言 1.1 Goroutine 调度器的 GMP 模型的设计思想 1.2 GMP 模型 1.3. 有关M和P的个数问题 1.4 P 和 M 何时会被创建 2. 调度器的设计策略 3. g ...

  8. 使用fiddler抓包模拟器及配置fiddler过滤

    一. 安装fiddler https://www.telerik.com/fiddler 二. 配置fiddler,一下的ip要根据自己电脑情况设置 然后重启Fiddler,一定要重启!!! 三.配置 ...

  9. Linux系列(42) - 防火墙相关命令

    # 开启 service firewalld start # 重启 service firewalld restart # 关闭 service firewalld stop # 查看防火墙规则 fi ...

  10. jmeter 录制排除模式

    jmeter录制时,静态的资源不需要,可以在录制的时候直接排除. .*\.(bmp|css|js|gif|icov|jpeg|png|swf|woff|woff2|htm|html).* .*\.(j ...