[技术博客] 利用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. RT-Thread 4.0 + STM32F407 学习笔记1

    RT Thread 4.0提供了新的BSP框架 新 BSP 框架的主要特性如下: 提供多系列 BSP 模板,大大降低新 BSP 的添加难度: 每个 BSP 都配有齐全的驱动文件,开发者可以方便地使用所 ...

  2. L2TP协议简介

    传送门:L2TP代码实现 1. L2TP 概述 L2TP(Layer 2 Tunneling Protocol,二层隧道协议)是 VPDN(Virtual Private Dial-up Networ ...

  3. try/catch捕获处理异常

    1.throws是中断处理,后续代码不能执行 try/catch方法体之后的后续代码有没有异常都可以继续执行: 2.当try方法体中出现异常才会执行catch方法体中代码

  4. K8s工作流程详解

    在学习k8s工作流程之前,我们得再次认识一下上篇k8s架构与组件详解中提到的kube-controller-manager一个k8s中许多控制器的进程的集合. 比如Deployment 控制器(Dep ...

  5. 使用tasker定时打开一耳光应用

    比如现在要做一个:到9点钟自动打开"酷狗音乐"1.任务→点击"+"→填写"打开酷狗音乐"→点击"√"2.任务编辑→点击& ...

  6. python安装easyinstall/pip出错

    在Windows中装了python3.6,自然还要装pip.按度娘的提供的方法先下载easyinstall,然后在CMD下输入: python ez_setup.py 结果报错 ........... ...

  7. contos 安装 nginx

    参考链接https://blog.csdn.net/u011159417/article/details/80081992 https://blog.csdn.net/wangxy_job/artic ...

  8. Kettle启动时报错Cannot create java virtual machine & A java exception has occurred

    开源免费--最喜欢的四个字没有之一 1.官网下载 https://sourceforge.net/projects/pentaho/files/Data%20Integration/ 下载完后,解压即 ...

  9. Fortran学习笔记:02 流控制语句

    Fortran学习笔记目录 书接上回:Fortran学习笔记:01 基本格式与变量声明 流控制语句 IF语句 IF (逻辑表达式) THEN ... ELSE ... END IF SELECT-CA ...

  10. FastAPI(64)- Settings and Environment Variables 配置项和环境变量

    背景 在许多情况下,应用程序可能需要一些外部设置或配置,例如密钥.数据库凭据.电子邮件服务凭据等. 大多数这些设置都是可变的(可以更改),例如数据库 URL,很多可能是敏感数据,比如密码 出于这个原因 ...