SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。

主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstanceState保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整形、Int整形、String字符串型的保存。

SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下:

分析以下几个方法:

Android中得到SharedPreference的方式有四种:

  • ContextWrapper.getSharedPreferences(String name, int mode)
  • Activity.getPreferences(int mode)
  • PreferenceManager.getSharedPreferences()
  • PreferenceManager.getDefaultSharedPreferences(Context context)

下面我们一起来跟踪下它们的源码:
1.ContextWrapper.getSharedPreferences(String name,int mode)
 
可以看出,我们可以自己设置SharedPreference的名字与模式

一、getSharedPreferences(name,mode)

方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上;

方法的第二个参数指定文件的操作模式,共有四种操作模式。

四种操作模式分别为:

1. MODE_APPEND: 追加方式存储

2. MODE_PRIVATE: 私有方式存储,其他应用无法访问

3. MODE_WORLD_READABLE: 表示当前文件可以被其他应用读取

4. MODE_WORLD_WRITEABLE: 表示当前文件可以被其他应用写入

二、edit()方法获取editor对象

Editor editor = sharedPreferences.edit();

editor存储对象采用key-value键值对进行存放,editor.putString("name", "wujaycode");

通过commit()方法提交数据

与之对应的获取数据的方法:

SharedPreferences share=getSharedPreferences("Acitivity",Activity.MODE_WORLD_READABLE);

int i=share.getInt("i",0);

String str=share.getString("str","");

boolean flag=share.getBoolean("flag",false);

getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值

如果你想要删除通过SharedPreferences产生的文件,可以通过以下方法:

File file= new File("/data/data/"+getPackageName().toString()+"/shared_prefs","Activity.xml");

if(file.exists()){

file.delete();

Toast.makeText(TestActivity.this, "删除成功", Toast.LENGTH_LONG).show(); }

三、访问其他应用中的Preference

如果要访问其他应用中的Preference,必须满足的条件是,要访问的应用的Preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。

举例,假如有个<package name>为com.wujay.action下面的应用使用了下面语句创建了Preference,getSharedPreferences("wujay", Context.MODE_WORLD_READABLE),

现在要访问该Preferences:

首先,需要创建上面的Context,然后通过Context访问Preferences,访问preference时会在应用所在包下的shared_prefs目录找到preference:

Context otherAppsContext = createPackageContext("com.wujay.action", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("wujay", Context.MODE_WORLD_READABLE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 0);

如果不通过创建Context访问其他应用的preference,可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:
File xmlFile = new File(“/data/data/<package name>/shared_prefs/itcast.xml”);//<package name>应替换成应用的包名。

2.Activity.getPreferences(int mode)
 
这种方式下,name是通过getLocalClassName()得到的,不能让我们自己设置,而且最终会调到ContextWrapper的getSharedPreferences(),getLocalClassName()定义如下:

3.PreferenceManager.getSharedPreferences()
 
这种方式我们是让PreferenceManager给我们维护一个SharedPreference,当然我们可以调用PreferenceManager的API来设置name和mode,并且最终也是调用到ContextWrapper的getSharedPreferences
4.PreferenceManager.getDefaultSharedPreferences(Context context)
 
这种方式得到的SharedPreference是某个包名下共享的,并且是私有的,不能让其他的包访问,而且Name和mode不能设置。最终也会调用到ContextWrapper的getSharedPreferences

总结:

获取SharedPreferences的两种方式:
1 调用Context对象的getSharedPreferences()方法
2 调用Activity对象的getPreferences()方法
两种方式的区别:
调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享.
调用Activity对象的getPreferences()方法获得的SharedPreferences对象只能在该Activity中使用.

使用方法

1、存数据

1 SharedPreferences sp = getSharedPreferences("sp_demo", Context.MODE_PRIVATE);
2 sp.edit().putString("name", "小张").putInt("age", 11).commit();

或者下面的写法也可以

1 SharedPreferences sp = getSharedPreferences("sp_demo", Context.MODE_PRIVATE);
2 Editor editor = sp.edit();
3 editor.putString("name", "小张");
4 editor.putInt("age", 11);
5 editor.commit();

切记不要写成下面的形式,会导致数据无法存储

1 SharedPreferences sp = getSharedPreferences("sp_demo", Context.MODE_PRIVATE);
2 sp.edit().putString("name", "小张");
3 sp.edit().putInt("age", 11);
4 sp.edit().commit();

为什么这种方式无法存储,因为sp.edit()每次都会返回一个新的Editor对象,Editor的实现类EditorImpl里面会有一个缓存的Map,最后commit的时候先将缓存里面的Map写入内存中的Map,然后将内存中的Map写进XML文件中。使用上面的方式commit,由于sp.edit()又重新返回了一个新的Editor对象,缓存中的Map是空的,所以导致数据无法被存储。

2、取数据

1 SharedPreferences sp = getSharedPreferences("sp_demo", Context.MODE_PRIVATE);
2 String name = sp.getString("name", null);
3 int age = sp.getInt("age", 0);

getSharedPreferences的具体实现是在frameworks/base/core/java/android/app/ContextImpl.java,代码如下:

 1 @Override
 2 public SharedPreferences getSharedPreferences(String name, int mode) {
 3     SharedPreferencesImpl sp;
 4     synchronized (ContextImpl.class) {
 5         ......
 6         final String packageName = getPackageName();
 7         ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
 8         if (packagePrefs == null) {
 9             packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
10             sSharedPrefs.put(packageName, packagePrefs);
11         }
12
13         ......
14         sp = packagePrefs.get(name);
15         if (sp == null) {
16             File prefsFile = getSharedPrefsFile(name);
17             sp = new SharedPreferencesImpl(prefsFile, mode);
18             packagePrefs.put(name, sp);
19             return sp;
20         }
21     }
22     ......
23     return sp;
24 }

SharedPreferencesImpl是SharedPreferences接口的具体实现类,一个name对应一个SharedPreferencesImpl,一个应用程序中根据name的不同会有多个SharedPreferencesImpl。 
SharedPreferencesImpl的具体实现是在frameworks/base/core/java/android/app/SharedPreferencesImpl.java,我们可以通过getSharedPreferences获得

SharedPreferences sharedPreferences = getSharedPreferences("ljq", Context.MODE_PRIVATE);

//getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值

String name = sharedPreferences.getString("name", "");

int age = sharedPreferences.getInt("age", 1);

如果访问其他应用中的Preference,前提条件是:该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。

如:有个<package name>为com.ljq.action的应用使用下面语句创建了preference。

getSharedPreferences("ljq", Context.MODE_WORLD_READABLE);

其他应用要访问上面应用的preference,首先需要创建上面应用的Context,然后通过Context 访问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference :

Context otherAppsContext = createPackageContext("com.ljq.action", Context.CONTEXT_IGNORE_SECURITY);

SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("ljq", Context.MODE_WORLD_READABLE);

String name = sharedPreferences.getString("name", "");

int age = sharedPreferences.getInt("age", 0);

如果不通过创建Context访问其他应用的preference,也可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:

File xmlFile = new File("/data/data/<package name>/shared_prefs/itcast.xml");//<package name>应替换成应用的包名

案例:

string.xml文件

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     <string name="hello">Hello World, SpActivity!</string>
4     <string name="app_name">软件配置参数</string>
5     <string name="name">姓名</string>
6     <string name="age">年龄</string>
7     <string name="button">保存设置</string>
8     <string name="showButton">显示</string>
9 </resources>

main.xml布局文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical"
 4     android:layout_width="fill_parent"
 5     android:layout_height="fill_parent">
 6     <RelativeLayout
 7         xmlns:android="http://schemas.android.com/apk/res/android"
 8         android:layout_width="wrap_content"
 9         android:layout_height="wrap_content">
10         <TextView android:layout_width="wrap_content"
11             android:layout_height="wrap_content"
12             android:text="@string/name"
13             android:textSize="20px"
14             android:id="@+id/nameLable" />
15         <EditText android:layout_width="80px"
16             android:layout_height="wrap_content"
17             android:layout_toRightOf="@id/nameLable"
18             android:layout_alignTop="@id/nameLable"
19             android:layout_marginLeft="10px"
20             android:id="@+id/name" />
21     </RelativeLayout>
22     <RelativeLayout
23         xmlns:android="http://schemas.android.com/apk/res/android"
24         android:layout_width="wrap_content"
25         android:layout_height="wrap_content">
26         <TextView android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:textSize="20px"
29             android:text="@string/age"
30             android:id="@+id/ageLable" />
31         <EditText android:layout_width="80px"
32             android:layout_height="wrap_content"
33             android:layout_toRightOf="@id/ageLable"
34             android:layout_alignTop="@id/ageLable"
35             android:layout_marginLeft="10px"
36             android:id="@+id/age" />
37     </RelativeLayout>
38     <RelativeLayout
39         xmlns:android="http://schemas.android.com/apk/res/android"
40         android:layout_width="wrap_content"
41         android:layout_height="wrap_content">
42         <Button android:layout_width="wrap_content"
43             android:layout_height="wrap_content"
44             android:text="@string/button"
45             android:id="@+id/button" />
46         <Button android:layout_width="wrap_content"
47             android:layout_height="wrap_content"
48             android:text="@string/showButton"
49             android:layout_toRightOf="@id/button"
50             android:layout_alignTop="@id/button"
51             android:id="@+id/showButton" />
52     </RelativeLayout>
53     <TextView android:layout_width="fill_parent"
54             android:layout_height="wrap_content"
55             android:textSize="20px"
56             android:id="@+id/showText" />
57 </LinearLayout>

 1 package com.ljq.activity;
 2
 3 import android.app.Activity;
 4 import android.content.Context;
 5 import android.content.SharedPreferences;
 6 import android.content.SharedPreferences.Editor;
 7 import android.os.Bundle;
 8 import android.view.View;
 9 import android.widget.Button;
10 import android.widget.EditText;
11 import android.widget.TextView;
12 import android.widget.Toast;
13
14 public class SpActivity extends Activity {
15     private EditText nameText;
16     private EditText ageText;
17     private TextView resultText;
18     @Override
19     public void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.main);
22
23         nameText = (EditText)this.findViewById(R.id.name);
24         ageText = (EditText)this.findViewById(R.id.age);
25         resultText = (TextView)this.findViewById(R.id.showText);
26
27         Button button = (Button)this.findViewById(R.id.button);
28         Button showButton = (Button)this.findViewById(R.id.showButton);
29         button.setOnClickListener(listener);
30         showButton.setOnClickListener(listener);
31
32         // 回显
33         SharedPreferences sharedPreferences=getSharedPreferences("ljq123",
34                 Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
35         String nameValue = sharedPreferences.getString("name", "");
36         int ageValue = sharedPreferences.getInt("age", 1);
37         nameText.setText(nameValue);
38         ageText.setText(String.valueOf(ageValue));
39     }
40
41     private View.OnClickListener listener = new View.OnClickListener(){
42         public void onClick(View v) {
43             Button button = (Button)v;
44             //ljq123文件存放在/data/data/<package name>/shared_prefs目录下
45             SharedPreferences sharedPreferences=getSharedPreferences("ljq123",
46                     Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
47             switch (button.getId()) {
48             case R.id.button:
49                 String name = nameText.getText().toString();
50                 int age = Integer.parseInt(ageText.getText().toString());
51                 Editor editor = sharedPreferences.edit(); //获取编辑器
52                 editor.putString("name", name);
53                 editor.putInt("age", age);
54                 editor.commit();//提交修改
55                 Toast.makeText(SpActivity.this, "保存成功", Toast.LENGTH_LONG).show();
56                 break;
57             case R.id.showButton:
58                 String nameValue = sharedPreferences.getString("name", "");
59                 int ageValue = sharedPreferences.getInt("age", 1);
60                 resultText.setText("姓名:" + nameValue + ",年龄:" + ageValue);
61                 break;
62             }
63         }
64     };
65 }

运行结果

如何访问其他应用中的Preference?

 1 package com.ljq.sp;
 2
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5
 6 import android.content.Context;
 7 import android.content.SharedPreferences;
 8 import android.test.AndroidTestCase;
 9 import android.util.Log;
10
11 public class AccessSharePreferenceTest extends AndroidTestCase{
12     private static final String TAG = "AccessSharePreferenceTest";
13
14     /**
15      * 访问SharePreference的方式一,注:权限要足够
16      * @throws Exception
17      */
18     public void testAccessPreference() throws Exception{
19         String path = "/data/data/com.ljq.activity/shared_prefs/ljq123.xml";
20         File file = new File(path);
21         FileInputStream inputStream = new FileInputStream(file);
22         //获取的是一个xml字符串
23         String data = new FileService().read(inputStream);
24         Log.i(TAG, data);
25     }
26
27     /**
28      * 访问SharePreference的方式二,注:权限要足够
29      * @throws Exception
30      */
31     public void testAccessPreference2() throws Exception{
32         Context context = this.getContext().createPackageContext("com.ljq.activity",
33                 Context.CONTEXT_IGNORE_SECURITY);
34         SharedPreferences sharedPreferences = context.getSharedPreferences("ljq123",
35                 Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
36         String name = sharedPreferences.getString("name", "");
37         int age = sharedPreferences.getInt("age", 1);
38         Log.i(TAG, name + " : " +age);
39     }
40 }

转载于:https://www.cnblogs.com/Im-Victor/p/6288658.html

[ Android 五种数据存储方式之一 ] —— SharedPreferences存储数据相关推荐

  1. android 7种网络连接方式--IT蓝豹

    2019独角兽企业重金招聘Python工程师标准>>> 本项目由作者 王永飞 精心为初学者准备的学习项目. android 几种网络连接方式,本项目适合初学者学习网络知识. 项目中用 ...

  2. 集丰照明|LED五种调光方式详解(DALI/DMX/0-10V/PWM/可控硅)

    LED五种调光方式详解 LED的发光原理同传统照明不同,同功率的 LED 光源,因其采用的芯片不同,电流电压参数则不同,故其内部布线结构和电路分布也不同,导致了各生产厂商的光源对调光驱动的要求也不尽相 ...

  3. Verilog VHDL三种建模描述方式——2选1数据选择器

    标题Quartus II 标题 Verilog VHDL三种建模描述方式--2选1数据选择器 1,结构化描述方式: 是使用实例化低层次模块的方法,即调用其他已经定义过的低层次模块对整个电路的功能进行描 ...

  4. 字符串的存储方式以及静态存储区域、栈、堆

    下面两篇文章分析得比较详细.转自http://blog.csdn.net/yangdelong/archive/2010/04/03/5447362.aspx 文章来源 http://blog.csd ...

  5. 动态存储方式和静态存储方式

    从变量的作用域的角度来观察,变量可以分为全局变量和局部变量: 全局变量都是存放在静态存储区中的.因此它们的生存期是固定的,存在于程序的整个运行过程 局部变量,如果不专门声明存储类别,都是动态地分配存储 ...

  6. 动态存储方式与静态存储方式

    从变量的作用域的角度来观察,变量可以分为全局变量和局部变量: 全局变量都是存放在静态存储区中的.因此它们的生存期是固定的,存在于程序的整个运行过程 局部变量,如果不专门声明存储类别,都是动态地分配存储 ...

  7. 串口MSComm控件五种不同校验方式对数据收发的影响

    (2008-09-10 14:50:00)   http://blog.sina.com.cn/s/blog_470eccc60100arq7.html   串口MSComm控件有五种校验方式,分别是 ...

  8. 【转】Android 面试题笔记-------android五种布局及其作用

    文章来源:http://blog.csdn.net/zhanglei1239/article/details/7354170 android常用的五种布局分别是:FrameLayout.LineaLa ...

  9. Ocelot简易教程(六)之重写配置文件存储方式并优化响应数据

    本来这篇文章在昨天晚上就能发布的,悲剧的是写了两三千字的文章居然没保存,结果我懵逼了.今天重新来写这篇文章.今天我们就一起来探讨下如何重写Ocelot配置文件的存储方式以及获取方式. 作者:依乐祝 原 ...

最新文章

  1. element 修改表单值后表单验证无效_javascript自学记录:表单脚本1
  2. hibernate hql limit的实现方式
  3. Win32ASM学习[15]:加减指令: INC、DEC、NEG、ADD、ADC、SUB、SBB、CMP
  4. C++ 标准库 vector list map使用方法
  5. NOI数学之提高级:线性方程组的高斯消元法
  6. autojs toast 可以改变字体颜色吗_喃喃札记 | 你真的需要一部pad做笔记吗?
  7. 肚子上挂张画就能隐身:AI完全看不出我在哪,更看不出我是人类了 | 开源
  8. GJB1188A校验C语言算法
  9. 读《Web全栈工程师的自我修养》
  10. 基于JSP网上购书系统
  11. remapkey不能打开注册表_解除封锁注册表被禁用的几种解决办法
  12. Win10无法访问共享文件,错误代码0x80004005
  13. 数据结构与算法Python版-第六周作业
  14. React- Hook 踩坑“useState“ is called in function “addP“ which is neither a React
  15. Js函数加括号、不加括号
  16. 人脸解锁手机与电影阿丽塔背后的3D原理:云从科技的技术突破
  17. 第一次尝试节奏跑(乳酸门槛跑)
  18. 这是2021年个人所得税税率表
  19. 只需简单几步 国行Xbox One就可以完美解除锁服
  20. ASP.NET MVC图片文件上传与下载

热门文章

  1. word中写论文常用的功能
  2. HTML制作宣传片,楼盘宣传片制作方法
  3. java游戏boss是冰龙_居然是个美少年?《龙之谷》新Boss冰龙将开
  4. hashCode相关性能优化
  5. 9-19作业-宋俊杰
  6. gitea Windows服务器更换logo图标
  7. 2019(第八届)国际桥梁与隧道技术大会将于2019年5月在上海举办!
  8. 医生和强盗,挺有意思
  9. python数据分析可视化大众点评网餐厅口碑包含数据
  10. 手写数字识别系统之数字提取