AndroidSharedPreferences数据存储原理解析及使用示例

更新时间:2023-08-02 02:13:16 阅读: 评论:0

AndroidSharedPreferences数据存储原理解析及使⽤⽰例
⼀、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);
第⼀个参数是⽣成l⽂件的⽂件名字,第⼆个参数是⽂件的访问权限以及⽂件数据写⼊⽅式。
简单说明⼀下⼏种⽅式:
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);
// 提交所有存⼊的数据
⽅法⼆:
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 = String("name", "");
// 读取int类型的数据
int age = Int("age", 0);
getSharedPreferences的具体实现是frameworks/ba/core/java/android/app/ContextImpl.java,代码如下:
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
synchronized (ContextImpl.class) {
......
final String packageName = getPackageName();
ArrayMap<String, SharedPreferencesImpl> packagePrefs = (packageName);
if (packagePrefs == null) {
packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
sSharedPrefs.put(packageName, packagePrefs);
}
......
sp = (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/ba/core/java/android/app/SharedPreferencesImpl.java,我们可以通过getSharedPreferences获得SharedPreferences的实例,当我们调⽤sp.getString等get⽅法取数据时,实际上是直接从内存中的Map⾥
⾯去取,get⽅法传⼊的第⼀个参数正好是Map的key,第⼆个参数是当Map中没有这个key对应值的时候,返回的默认值。
4)监听数据变化
SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeList @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
};
preferences.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);//解注册数据变化监听
5)具体写⼊⽂件的存储结构
存储在⽂件中就是这样的,纯明⽂存储没有⼀点安全性可⾔。即使设置了Activity.MODE_PRIVATE权限在ROOT权限⾯前也是不堪⼀击的。所以我们在使⽤SharedPreferences的时候尽量不要存储⼀些有关⽤户信息的数据,如果要存储那该怎么补救呢?我们可以把key和value的值采⽤加密算法加密⼀下。
三、使⽤⽰例
简单设计⼀个应⽤,让⽤户输⼊姓名和年龄,然后将数据保存到SharedPreferences,之后读取SharedPreferences数据并在界⾯上显⽰出来。当⽤户修改数据重新保存以后,提⽰SharedPreferences数据发⽣变化。界⾯如下图:
⾸先是布局⽂件,
<LinearLayout xmlns:android="/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.sharedpreferencestest;
import android.app.Activity;
t.Context;
t.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)
{
tContentView(R.layout.activity_main);
etWriteName = (EditText) findViewById(WriteName);
etWriteAge = (EditText) findViewById(WriteAge);
tvRead = (TextView) findViewById(R.id.tvReadData);
write = (Button) findViewById(R.id.write);
read = (Button) findViewById(ad);
//获取只能被本应⽤程序读写的SharedPreferences对象,
//保存的⽂件名为l
preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
//实例化SharedPreferences.Editor对象
editor = preferences.edit();
//注册数据变化监听
onSharedPreferenceChangeListener);
write.tOnClickListener(new OnClickListener()
先秦诸子百家>餐厅简笔画{
@Override
public void onClick(View arg0)
{
// 存⼊⽤户姓名
editor.putString("name", Text().toString());
//存⼊⽤户年龄
editor.putInt("age",Integer.Text().toString()));
/
/ 提交所有存⼊的数据
}
});
read.tOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
// 读取字符串数据
String name = String("name", "");
平凡世界读后感/
/ 读取int类型的数据
int age = Int("age", 0);
//显⽰读取出来的数据
tvRead.tText("姓名: "+name+"\n年龄: "+age);
}大熊猫的故事
});

本文发布于:2023-08-02 02:13:16,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1126296.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   程序   保存   读取   实例   变化   监听   时候
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图