Android SharedPreferences数据存储原理解析及使用示例
来源:互联网 发布:郑州大学软件学院2017 编辑:程序博客网 时间:2024/05/24 00:51
一、SharedPreferences简介
SharedPreferences是基础key-value(键值对)来存储一些轻量数据的存储方式,特别适用于保存软件配置参数。使用SharedPreferences 保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<
package name>
/shared_prefs。
SharedPreferences主要特点:
- 适合于少量数据的保存 ;
- 保存的数据只支持Java基本数据类型,不支持自定义数据类型;
- 使用简单。
二、使用方法
1)获取SharedPreferences实例
SharedPreferences本身是一个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name,int mode)方法来获取SharedPreferences实例。例如:
// 获取只能被本应用程序读、写的SharedPreferences对象SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
第一个参数是生成xxx.xml文件的文件名字,第二个参数是文件的访问权限以及文件数据写入方式。
简单说明一下几种方式:
Context.MODE_PRIVATE: //指定该SharedPreferences数据只能被本应用程序读写。
Context.MODE_WORLD_READABLE: //指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE: //指定该SharedPreferences数据能被其他应用程序读写。
注意:从Android4.2开始, Android不再推荐使用 MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE这两种模式, 因为这两种模式允许其他应用程序来读或写本应用创建的数据, 因此容易导致安全漏洞 。 如果应用程序确实需要把内部数据暴露出来供其他应用访司, 则应该使用 ContentProvider。
2)写入数据
方法一:
//获取SharedPreferences实例SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);//实例化SharedPreferences.Editor对象editor = preferences.edit();// 存入用户姓名editor.putString("name", "yourname");//存入用户年龄 editor.putInt("age",18);// 提交所有存入的数据editor.commit();
方法二:
SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);preferences.edit().putString("name", "yourname").putInt("age", 18).commit();
切记:不要写成下面的形式,会导致数据无法存储。
SharedPreferences sp = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);sp.edit().putString("name", "yourname");sp.edit().putInt("age", 18);sp.edit().commit();
为什么这种方式无法存储? 因为sp.edit()每次都会返回一个新的Editor对象,Editor的实现类EditorImpl里面会有一个缓存的Map,最后commit的时候先将缓存里面的Map写入内存中的Map,然后将内存中的Map写进XML文件中。使用上面的方式commit,由于sp.edit()又重新返回了一个新的Editor对象,缓存中的Map是空的,所以导致数据无法被存储。
3)读取数据
//获取SharedPreferences实例SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);// 读取字符串数据String name = preferences.getString("name", "");// 读取int类型的数据int age = preferences.getInt("age", 0);
getSharedPreferences的具体实现是frameworks/base/core/java/android/app/ContextImpl.java,代码如下:
@Overridepublic SharedPreferences getSharedPreferences(String name, int mode) { SharedPreferencesImpl sp; synchronized (ContextImpl.class) { ...... final String packageName = getPackageName(); ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName); if (packagePrefs == null) { packagePrefs = new ArrayMap<String, SharedPreferencesImpl>(); sSharedPrefs.put(packageName, packagePrefs); } ...... sp = packagePrefs.get(name); if (sp == null) { File prefsFile = getSharedPrefsFile(name); sp = new SharedPreferencesImpl(prefsFile, mode); packagePrefs.put(name, sp); return sp; } } ...... return sp;}
SharedPreferencesImpl是SharedPreferences接口的具体实现类,一个name对应一个SharedPreferencesImpl,一个应用程序中根据name的不同会有多个SharedPreferencesImpl。
SharedPreferencesImpl的具体实现是在frameworks/base/core/java/android/app/SharedPreferencesImpl.java,我们可以通过getSharedPreferences获得SharedPreferences的实例,当我们调用sp.getString等get方法取数据时,实际上是直接从内存中的Map里面去取,get方法传入的第一个参数正好是Map的key,第二个参数是当Map中没有这个key对应值的时候,返回的默认值。
4)监听数据变化
SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { } }; preferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);//注册数据变化监听 preferences.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);//解注册数据变化监听
5)具体写入文件的存储结构
存储在文件中就是这样的,纯明文存储没有一点安全性可言。即使设置了Activity.MODE_PRIVATE权限在ROOT权限面前也是不堪一击的。所以我们在使用SharedPreferences的时候尽量不要存储一些有关用户信息的数据,如果要存储那该怎么补救呢?我们可以把key和value的值采用加密算法加密一下。
三、使用示例
简单设计一个应用,让用户输入姓名和年龄,然后将数据保存到SharedPreferences,之后读取SharedPreferences数据并在界面上显示出来。当用户修改数据重新保存以后,提示SharedPreferences数据发生变化。界面如下图:
首先是布局文件,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="50dp" android:paddingLeft="100dp"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/name" android:textAppearance="?android:attr/textAppearanceLarge"/> <EditText android:id="@+id/etWriteName" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/write_name" android:textAppearance="?android:attr/textAppearanceLarge"/> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/age" android:textAppearance="?android:attr/textAppearanceLarge"/> <EditText android:id="@+id/etWriteAge" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/write_age" android:textAppearance="?android:attr/textAppearanceLarge"/> </LinearLayout> <Button android:id="@+id/write" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/write" android:textAppearance="?android:attr/textAppearanceLarge"/> <Button android:id="@+id/read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/read" android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView android:id="@+id/tvReadData" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"/></LinearLayout>
然后是主程序代码,
package cl.fjnu.edu.cn.sharedpreferencestest;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity{ SharedPreferences preferences; SharedPreferences.Editor editor; private EditText etWriteName; private EditText etWriteAge; private TextView tvRead; private Button read; private Button write; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etWriteName = (EditText) findViewById(R.id.etWriteName); etWriteAge = (EditText) findViewById(R.id.etWriteAge); tvRead = (TextView) findViewById(R.id.tvReadData); write = (Button) findViewById(R.id.write); read = (Button) findViewById(R.id.read); //获取只能被本应用程序读写的SharedPreferences对象, //保存的文件名为sharedPrefFile.xml preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE); //实例化SharedPreferences.Editor对象 editor = preferences.edit(); //注册数据变化监听 preferences.registerOnSharedPreferenceChangeListener( onSharedPreferenceChangeListener); write.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 存入用户姓名 editor.putString("name", etWriteName.getText().toString()); //存入用户年龄 editor.putInt("age",Integer.parseInt(etWriteAge.getText().toString())); // 提交所有存入的数据 editor.commit(); } }); read.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 读取字符串数据 String name = preferences.getString("name", ""); // 读取int类型的数据 int age = preferences.getInt("age", 0); //显示读取出来的数据 tvRead.setText("姓名: "+name+"\n年龄: "+age); } }); } //数据变化监听器 SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Toast.makeText(MainActivity.this,"sharedPrefTest文件数据发生了变化!",Toast.LENGTH_SHORT).show(); } };}
运行效果:
在姓名和年龄输入框分别输入数据,然后点击保存数据,再读取数据,可以看到下方显示出用户保存的SharedPreferences数据。如下图,
修改输入数据,点击保存数据重新保存,则弹出Toast消息,提示SharedPreferences数据已发生变化。如下图所示,
此时再点击读取数据,则会显示出更新过的SharedPreferences数据。如下图,
- Android SharedPreferences数据存储原理解析及使用示例
- Android SharedPreferences数据存储原理解析及使用示例
- Android 使用SharedPreferences数据存储
- Android中使用SharedPreferences进行数据存储及文件操作
- Android 简单数据存储之SharedPreferences简介(含方法及示例)
- Android数据存储---SharedPreferences详解及应用
- Hello Android - 使用SharedPreferences存储数据
- Android中使用SharedPreferences进行数据存储
- Android 使用SharedPreferences进行数据存储
- Android使用SharedPreferences进行数据存储
- Android笔记使用SharedPreferences进行数据存储
- 【Android 基础】数据存储SharedPreferences 使用
- Android-数据存储SharedPreferences的使用
- Android数据存储-SharedPreferences
- Android数据存储---SharedPreferences
- Android数据存储---SharedPreferences
- android SharedPreferences数据存储
- Android 数据存储 -- SharedPreferences
- Spring--AOP
- 上传高分资源,低分下载
- [21]DOM操作表格及样式
- [22]DOM元素尺寸和位置
- 449. Serialize and Deserialize BST
- Android SharedPreferences数据存储原理解析及使用示例
- ubuntu启动过程
- seoer的日常工作是什么
- 响应式网站的好处
- 网站内页参与排名的一些技巧
- word 操作类实现拆分word
- aspose.words 操作word生成试卷
- word 操作类实现拆分word
- jacob 操纵Microsoft Word 进行转移、拆分、合并、插入等操作 结合Freemarker将无所不能