上篇给大家讲解的是文件的存储,那么本篇为大家呈现的就是简单易学的SharedPreferences的存储与数据读取
sp:SharedPreferences
2020年补入一个小知识点 ~
SP存储的信息是否会因为app的卸载而清空呢?
其实用 SharedPreferences 保存的数据,卸载 App 后还存在 ~
搜寻之后发现从Android 6.0开始,它可以使用allowBackup属性的boolean来进行设置:
- true:数据将保存在Google云中,并在下次安装该应用程序时进行恢复
- false:数据将会在卸载app的时候同时做清空处理
<application
android:allowBackup="true">
</application>
实现效果
Start UI:
End UI:
前情提要
Android常见的存储方式,除去sp存储之外,还可以看看一下我早期写的 文件存储 ~
sp存储与文件存储区别
文件存储是以文本的形式存储,存的内容更多的是一整块内容,很难分化,而sp是以键值对的形式存储信息,所以扩展性更强,但是因为sp的存储空间并不大,虽然存储方便,但只是存一些细小的精确数据。
注意点
-
首先我们确认是存还是取,当然都会通过getSharedPreferences的方法,我们需要确认存储时候使用的文件名称与存储方式,存的时候我们因为是输入,所以会返回Editor,取的时候则不需要
-
SharedPreferences因为是键值对的存在,所以不论存取我们都需要对应处理,如我们之前没有存储部分键,则会返回我们设置的默认值
开发实践
添加读写权限(新手朋友要注意现在基本都会用到6.0的动态权限)
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_PROFILE"/>
MainActivity
package com.example.spstorage;
import android.os.Bundle;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private TextView mContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mContent = (TextView) findViewById(R.id.main_content);
Button mSave = (Button) findViewById(R.id.save_one);
Button mLoad = (Button) findViewById(R.id.load_one);
mSave.setOnClickListener(this);
mLoad.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.save_one:
onSave();
break;
case R.id.load_one:
onRead();
break;
default:
break;
}
}
//数据保存在sp中
private void onSave() {
//带有Editor类型的均为输入,也就是存储
Editor editor = MainActivity.this.getSharedPreferences("sp_data", MODE_PRIVATE).edit();
editor.putString("name", "Jack");
editor.putInt("age", 18);
//这里要记得提交,不然数据没保存进去
editor.apply();
}
//读取SP内的信息
private void onRead() {
//像这样不是Editor类型的就是读取数据了,通过键获取值
SharedPreferences spData = getSharedPreferences("sp_data", MODE_PRIVATE);
//通过键值对获取我们刚才存储的信息
String name = spData.getString("name", "");
int age = spData.getInt("age", 0);
mContent.setText("我们存储在sp的姓名:"+name+"-----存储的年龄:"+age);
}
}
activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/main_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="在此输入要保存的信息"
/>
<Button
android:id="@+id/save_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SP保存" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/load_one"
android:text="读取sp的数据"
android:gravity="center"
/>
<TextView
android:id="@+id/main_content"
android:text="读取数据展示区"
android:gravity="center"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
SP工具类
SpUtil
package com.nk.machine.tools;
/**
* @author Administrator
* @date 2017/1/3
* desc:
*/
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.List;
/**
* SharedPreferences工具类, 可以通过传入实体对象保存其至SharedPreferences中,
* 并通过实体的类型Class将保存的对象取出. 支持不带泛型的对象以及List集合
*/
public class SpUtil {
private static final String LIST_TAG = ".LIST";
private static SharedPreferences sharedPreferences;
private static Gson gson;
/**
* 使用之前初始化, 可在Application中调用
* @param context 请传入ApplicationContext避免内存泄漏
*/
public static void init(Context context) {
sharedPreferences = context.getSharedPreferences("shared_files", Context.MODE_PRIVATE);
gson = new Gson();
}
private static void checkInit() {
if (sharedPreferences == null || gson == null) {
throw new IllegalStateException("Please call init(context) first.");
}
}
/**
* 保存对象数据至SharedPreferences, key默认为类名, 如
* <pre>
* PreferencesHelper.putData(saveUser);
* </pre>
* @param data 不带泛型的任意数据类型实例
*/
public static <T> void putData(T data) {
putData(data.getClass().getName(), data);
}
/**
* 根据key保存对象数据至SharedPreferences, 如
* <pre>
* PreferencesHelper.putData(key, saveUser);
* </pre>
* @param data 不带泛型的任意数据类型实例
*/
public static <T> void putData(String key, T data) {
checkInit();
if (data == null) {
throw new IllegalStateException("data should not be null.");
}
String s = gson.toJson(data);
sharedPreferences.edit().putString(key, gson.toJson(data)).apply();
}
/**
* 保存List集合数据至SharedPreferences, 请确保List至少含有一个元素, 如
* <pre>
* PreferencesHelper.putData(users);
* </pre>
* @param data List类型实例
*/
public static <T> void putData(List<T> data) {
checkInit();
if (data == null || data.size() <= 0) {
throw new IllegalStateException(
"List should not be null or at least contains one element.");
}
Class returnType = data.get(0).getClass();
sharedPreferences.edit().putString(returnType.getName() + LIST_TAG, gson.toJson(data)).apply();
}
/**
* 保存List集合数据至SharedPreferences, 请确保List至少含有一个元素, 如
* <pre>
* PreferencesHelper.putData(users);
* </pre>
* @param data List类型实例
*/
public static <T> void putData(String key, List<T> data) {
checkInit();
if (data == null || data.size() <= 0) {
throw new IllegalStateException(
"List should not be null or at least contains one element.");
}
sharedPreferences.edit().putString(key, gson.toJson(data)).apply();
}
/**
* 将数据从SharedPreferences中取出, key默认为类名, 如
* <pre>
* User user = PreferencesHelper.getData(key, User.class)
* </pre>
* @param clz
*/
public static <T> T getData(String clz) {
return getData(clz);
}
/**
* 根据key将数据从SharedPreferences中取出, 如
* <pre>
* User user = PreferencesHelper.getData(User.class)
* </pre>
*/
public static <T> T getData(String key, Class<T> clz) {
checkInit();
String json = sharedPreferences.getString(key, "");
T t = gson.fromJson(json, clz);
return t;
}
/**
* 将数据从SharedPreferences中取出, 如
* <pre>List<User> users = PreferencesHelper.getData(List.class, User.class)</pre>
*/
public static <T> List<T> getData(Class<T> gClz) {
checkInit();
String json = sharedPreferences.getString(gClz.getName() + LIST_TAG, "");
return gson.fromJson(json, new TypeToken<List>() {
}.getType());
}
/**
* 将数据从SharedPreferences中取出, 如
* <pre>List<User> users = PreferencesHelper.getData(List.class, User.class)</pre>
*/
public static <T> List<T> getListData(String key, Class<T> gClz) {
checkInit();
String json = sharedPreferences.getString(key, "");
return gson.fromJson(json, new TypeToken<List>() {
}.getType());
}
/**
* 用于保存集合
*
* @param key key
* @param list 集合数据
* @return 保存结果
*/
public static <T> boolean putNewListData(String key, List<T> list) {
boolean result;
String type = list.get(0).getClass().getSimpleName();
SharedPreferences.Editor editor = sharedPreferences.edit();
JsonArray array = new JsonArray();
try {
switch (type) {
case "Boolean":
for (int i = 0; i < list.size(); i++) {
array.add((Boolean) list.get(i));
}
break;
case "Long":
for (int i = 0; i < list.size(); i++) {
array.add((Long) list.get(i));
}
break;
case "Float":
for (int i = 0; i < list.size(); i++) {
array.add((Float) list.get(i));
}
break;
case "String":
for (int i = 0; i < list.size(); i++) {
array.add((String) list.get(i));
}
break;
case "Integer":
for (int i = 0; i < list.size(); i++) {
array.add((Integer) list.get(i));
}
break;
default:
Gson gson = new Gson();
for (int i = 0; i < list.size(); i++) {
JsonElement obj = gson.toJsonTree(list.get(i));
array.add(obj);
}
break;
}
editor.putString(key, array.toString());
result = true;
} catch (Exception e) {
result = false;
e.printStackTrace();
}
editor.apply();
return result;
}
/**
* 获取保存的List
*
* @param key key
* @return 对应的Lis集合
*/
public static <T> List<T> getNewListData(String key, Class<T> cls) {
List<T> list = new ArrayList<>();
String json = sharedPreferences.getString(key, "");
if (!json.equals("") && json.length() > 0) {
Gson gson = new Gson();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (JsonElement elem : array) {
list.add(gson.fromJson(elem, cls));
}
}
return list;
}
/**
* 简易字符串保存, 仅支持字符串
*/
public static void putString(String key, String data) {
sharedPreferences.edit().putString(key, data).apply();
}
/**
* 简易字符串获取, 仅支持字符串
*/
public static String getString(String key) {
return sharedPreferences.getString(key, "");
}
public static void putInt(String key, int data) {
sharedPreferences.edit().putInt(key, data).apply();
}
public static int getInt(String key) {
return sharedPreferences.getInt(key, 0);
}
public static void putBoolean(String key, boolean data) {
sharedPreferences.edit().putBoolean(key, data).apply();
}
public static boolean getBoolean(String key, boolean defaultData) {
return sharedPreferences.getBoolean(key, defaultData);
}
public static void putFloat(String key, float data) {
sharedPreferences.edit().putFloat(key, data).apply();
}
public static float getFloat(String key, float defaultData) {
return sharedPreferences.getFloat(key, defaultData);
}
public static void putLong(String key, long data) {
sharedPreferences.edit().putLong(key, data).apply();
}
public static float getLong(String key, long defaultData) {
return sharedPreferences.getLong(key, defaultData);
}
public static void clear() {
sharedPreferences.edit().clear().apply();
}
/**
* 删除保存的对象
*/
public static void remove(String key) {
sharedPreferences.edit().remove(key).apply();
}
/**
* 删除保存的对象
*/
public static void remove(Class clz) {
remove(clz.getName());
}
/**
* 删除保存的数组
*/
public static void removeList(Class clz) {
sharedPreferences.edit().remove(clz.getName() + LIST_TAG).apply();
}
}
DDMS查看SP内容
我们发现存储的数据及为代码中:
我们可以通过DDMS查看数据保存结果:
导出后的数据展示: