SharedPreferences是由Android提供的轻量级的存储方式,为什么叫它轻量级,主要是由于它只能够存储Java基本类型的数据。其底层实现也是借助共享文件(具体实现为XML文件),只不过Android基于Java的文件系统又再次做了一些封装,使其调用起来更为简单和方便。

本文还是通过写Demo的形式,来对SharedPreferences的常见使用方式来进行一个介绍。

SharedPreferencesActivity的代码如下:

package com.itachi.android.sharedpreferencesdemo;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;import com.itachi.android.sharedpreferencesdemo.util.SharedPreferencesUtils;public class SharedPreferencesActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG = "SharedPreferencesActivtiy";private static final String CUSTOM_PREFERENCES_NAME = "CustomPreferences";private EditText mUsername;private EditText mAge;private Button mWriteToApplications;private Button mWriteToActivitys;private Button mWriteToCustom;private Button mToOtherActivity;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_shared_preferences);mUsername = findViewById(R.id.user_name);mAge = findViewById(R.id.user_age);mWriteToApplications = findViewById(R.id.button_write_to_applications_preferences);mWriteToActivitys = findViewById(R.id.button_write_to_current_activitys_preferences);mWriteToCustom = findViewById(R.id.button_write_to_custom_preferences);mToOtherActivity = findViewById(R.id.to_other_activity);mWriteToApplications.setOnClickListener(this);mWriteToActivitys.setOnClickListener(this);mWriteToCustom.setOnClickListener(this);mToOtherActivity.setOnClickListener(this);}private void writeToPreferences(SharedPreferences preferences) {SharedPreferences.Editor editor = preferences.edit();String username = mUsername.getText().toString();int age = Integer.valueOf(TextUtils.isEmpty(mAge.getText()) ? "-1" : mAge.getText().toString());editor.putString("Username", username);editor.putInt("Age", age);editor.commit();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button_write_to_applications_preferences:writeToPreferences(SharedPreferencesUtils.getCurrentApplicationSharedPreferences(this, MODE_PRIVATE));break;case R.id.button_write_to_current_activitys_preferences:writeToPreferences(SharedPreferencesUtils.getCurrentActivityPreferences(this, MODE_PRIVATE));break;case R.id.button_write_to_custom_preferences:writeToPreferences(SharedPreferencesUtils.getPreferencesByName(this, CUSTOM_PREFERENCES_NAME, MODE_PRIVATE));break;case R.id.to_other_activity:Intent intent = new Intent(this, OtherActivity.class);startActivity(intent);break;default:break;}}
}

SharedPreferencesUtils的代码如下:

package com.itachi.android.sharedpreferencesdemo.util;import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;public class SharedPreferencesUtils {private static final String APPLICATION_NAME = "SharedPreferencesDemo";public static SharedPreferences getCurrentApplicationSharedPreferences(Context context, int mode) {return context.getSharedPreferences(APPLICATION_NAME, mode);}public static SharedPreferences getCurrentActivityPreferences(Activity activity, int mode) {// 调用的是Activity类的getPreferences方法return activity.getPreferences(mode);}public static SharedPreferences getPreferencesByName(Context context, String name, int mode) {// 调用的是Context类的getPreferences方法return context.getSharedPreferences(name, mode);}
}

先来分析一下SharedPreferencesUtils这个工具类的方法,其中分别调用了Activity类的getPreferences方法和Context类的getSharedPreferences方法来返回我们所需要的SharedPreferences对象。

我们先看一下ContextImpl中实现的getSharedPreferences(String name, int mode)方法(Context只是个抽象类,真正实现是在ContextImpl类中),如下:

    @Overridepublic SharedPreferences getSharedPreferences(String name, int mode) {// At least one application in the world actually passes in a null// name.  This happened to work because when we generated the file name// we would stringify it to "null.xml".  Nice.if (mPackageInfo.getApplicationInfo().targetSdkVersion <Build.VERSION_CODES.KITKAT) {if (name == null) {name = "null";}}File file;synchronized (ContextImpl.class) {if (mSharedPrefsPaths == null) {mSharedPrefsPaths = new ArrayMap<>();}file = mSharedPrefsPaths.get(name);if (file == null) {file = getSharedPreferencesPath(name);mSharedPrefsPaths.put(name, file);}}return getSharedPreferences(file, mode);}@Overridepublic SharedPreferences getSharedPreferences(File file, int mode) {SharedPreferencesImpl sp;synchronized (ContextImpl.class) {final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();sp = cache.get(file);if (sp == null) {checkMode(mode);if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {if (isCredentialProtectedStorage()&& !getSystemService(UserManager.class).isUserUnlockingOrUnlocked(UserHandle.myUserId())) {throw new IllegalStateException("SharedPreferences in credential encrypted "+ "storage are not available until after user is unlocked");}}sp = new SharedPreferencesImpl(file, mode);cache.put(file, sp);return sp;}}if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {// If somebody else (some other process) changed the prefs// file behind our back, we reload it.  This has been the// historical (if undocumented) behavior.sp.startReloadIfChangedUnexpectedly();}return sp;}

具体细节就不仔细展开了,可以看到getSharedPreferences(String name, int mode)方法以我们传递进去的文件名创建了需要的xml文件,并调用getSharedPreferences(File file, int mode)方法返回我们需要的SharedPreferences对象。

我们再来看一下Activity类的getPreferences(int mode)方法,如下:

    /*** Retrieve a {@link SharedPreferences} object for accessing preferences* that are private to this activity.  This simply calls the underlying* {@link #getSharedPreferences(String, int)} method by passing in this activity's* class name as the preferences name.** @param mode Operating mode.  Use {@link #MODE_PRIVATE} for the default*             operation.** @return Returns the single SharedPreferences instance that can be used*         to retrieve and modify the preference values.*/public SharedPreferences getPreferences(@Context.PreferencesMode int mode) {return getSharedPreferences(getLocalClassName(), mode);}

可以看到最终也是通过调用Context类的getSharedPreferences(String name, int modef)方法(Activity类实现了Context类)来返回SharedPreferences对象,只不过它默认传递了当前的Activity名称作为底层文件名。并且从这个方法的注释上我们也能看出,getPreferences方法返回了一个当前Activity私有的SharedPreferences对象,它的实现方式就是通过将当前Activity名称作为Preferences的名称。

再来看一下Demo中写了什么吧,我们在SharedPreferencesActivity中分别定义了三个按钮,将Username和Age写入到当前Activity私有的Preferences和两个共享的Preferences中。并且在OtherActivity中通过直接将SharedPreferencesActivity作为文件名获取SharedPreferences,来访问到SharedPreferencesActivity私有的Preferences,验证了前面分析的Context和Activity类的代码。

Demo的演示效果如下:

通过Android Studio的Device File Explorer我们也可以看到,SharedPreferences默认被创建在"data/data/<应用包名>/shared_prefs/"目录下,如下图:

文件内容如下:

对于SharedPreferences,它的使用是非常简单的,总结来说有以下几个特点,

1.轻量级,基于XML文件存储,只支持Java基本数据类型。

2.不支持多进程,其实关于这个,我觉得并不严谨,只能说它的使用初衷本就不是为了解决跨进程通信,只是为了解决一些简单的数据共享问题。且也可以另辟蹊径来在不同进程中访问,通过Context.createPackageContext(String packageName, int flags)方法来创建其他进程的上下文对象,进而访问其他进程的SharedPreferences文件。

3.数据量过大会影响它的读写性能,这个没有具体研究,只是看到书中和其他博主有提过,后面如果有工作需求能够深入了解的话,会再来分析这个问题。

SharedPreferences牛刀小试相关推荐

  1. Android SharedPreferences 的使用

    学而时习之,稳固而之心,如果这边文章帮助了您,希望给一个赞 如果你只是着急使用忘记了方法 那么下面这些代码完全满足了您的使用 private static final String USER = &q ...

  2. Android开发之SharedPreferences的封装

    对于大部分初学者来说,如果想利用SharedPreferences进行数据存储的话大部分人(包括本人)应该会这样: 存储: SharedPreferences sharedPreferences = ...

  3. SharedPreferences的工具类,使用起来方便、快捷

    SharedPreferences的工具类,使用起来方便.快捷:上代码: import android.content.Context;import android.content.SharedPre ...

  4. Android SharedPreferences保存和读取对象

    SharedPreferences保存和读取对象 1.首先要序列化对象(以下是序列化实体类的样例,不方便贴出实体类全部的代码) public class LoginResult extends Bas ...

  5. Android之SharedPreferences详解

    SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的就是一个key-value(键值对)SharedPreferences常用来 ...

  6. SharedPreferences小细节

    废话不多讲,直接入题:以下,SharedPreferences小马就简称SP了: SP一般建议在全局文件中操作,即:在继承Application的扩展类中操作,这样做的原因是SP只是为了存储一些应用及 ...

  7. Android 中文api (88)——SharedPreferences

    前言 本章内容是android.content.SharedPreferences,版本为Android 2.3 r1,翻译来自"madgoat",欢迎大家访问他的博客:http: ...

  8. 实例教程五:采用SharedPreferences保存用户偏好设置参数

    android水管工人游戏源码 http://www.eoeandroid.com/thread-207446-1-1.html Android推箱子小游戏 http://www.eoeandroid ...

  9. android: SharedPreferences存储

    不同于文件的存储方式,SharedPreferences 是使用键值对的方式来存储数据的.也就是 说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可 以通过这个键把相应的 ...

  10. Android-02:使用SharedPreferences存储简单数据

    Android有许多数据存储的方式: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用ContentProvider存储数据 5 网络存储 ...

最新文章

  1. 增强for循环对于“二维”数组进行循环的案例
  2. flask第二十四篇——模板【6】自定义过滤器
  3. MyBatis Plus——忽略某个实体类属性和数据库表字段之间的映射关系
  4. vs.net 2003 错误:无法生成项目输出组“内容文件来自stuschool(活动)”
  5. java 网络驱动器_删除多余的网络驱动器
  6. ubuntu安装 rust nightly_Rust 嵌入式开发环境搭建指南 (一):让世界闪烁吧
  7. vue+vant 移动端H5 商城项目_03
  8. win7系统主板驱动在哪
  9. 数据库系统开发生命周期各个阶段需要获取的数据以及生成的文档
  10. 面试官:来,说说图片防盗链实现?
  11. 主机动手系列 — 不同CPU,不同命令,怎么管理HP-UX服务器
  12. 黑洞内部垂直向上发射光子,会怎样
  13. do something for your dream
  14. Qt实战案例(13)——Qt的界面外观详细介绍
  15. MTK平台CAMERA驱动框架解析
  16. 阿里云服务器搭建halo博客从0到1
  17. Github每日精选(第17期):Django下的内容管理系统wagtail
  18. 【报名开启】2021年博客之星总评选,属于你的年终表彰
  19. 互联网晚报 | 1月3日 星期一 | 春运首日火车票今日开售;中兴终端2021年出货量超1亿部;抖音上线“学习”频道...
  20. Mac技巧:新手必看Macbook快捷键使用大全

热门文章

  1. Windows 7精简版(2019.04.10)
  2. 别了dvorak!-----论qwert、dvorak布局优劣
  3. python代码图片头像_Python爬取堆糖网优美古风头像(附源码)
  4. 张小龙2019微信公开课演讲实录
  5. 如何把录音生成二维码,用微信扫一下就能听?分享语音音频转二维码的方法和技术原理
  6. vs(c++)修改图标
  7. 是修修补补,还是买件新衣
  8. 获取素材列表返回40004 invalid media type.获取公众号素材mediaId
  9. 布局平板电脑 英特尔Atom新核芯全解析
  10. 计算机网络应用层题库