Android 数据储存之SharedPreferences(SP)详解以及工具类SPUtils

作为 Android 的数据储存方式之一的 SharedPreferences(以下简称SP),我们在开发中也是或多或少会用到。今天就来介绍一下SP功能以及总结一下SP的用法。

首先我们来介绍一下SP:

  • SP 使所有应用程序共享它的同一个实例,通过 XML 以 key-value 的形式保存数据,保证了数据的一致性(但这可能会导致你的应用程序变得很慢,所以需要慎用),同时 SP 是不支持多进程读写操作的。
  • 应用场景:主要用来保存一些轻量级的数据(字符串、基本数据类型),比如应用程序的各种配置信息,以及一些简单的账号、密码等。
  • SP 的数据文件储存位置:data/data/应用程序包名/shared_prefs/
  • SP 的权限
MODE_PRIVATR 默认模式,创建保存的文件只能本应用程序或者拥有相同用户ID的应用程序访问
MODE_WORLD_READABLE 允许所有应用程序对创建的文件进行读操作权限(官方不建议使用,数据不安全)
MODE_WORLD_WRITEABLE 允许所有应用程序对创建的文件进行写操作权限(官方不建议使用,数据不安全)
MODE_MULTI_PROCESS 设置后,即使已经在此进程中加载了SP的实例,也会检查磁盘文件是否有修改,在多进程的情况下,或许需要此功能,但是通常进程间通信会用别的更好的方式。这是Gingerbread(Android 2.3)之前和之前的遗留(但未记录)行为,并且在定位此类版本时隐含了此标志。 对于针对大于Android 2.3的SDK版本的应用程序,必须根据需要显式设置此标志。
  • SP的方法
adstract  boolean

contains(String key)

检查SP文件是否包含此 key。

adstract  SharedPreferences.Editor

edit()

创建一个SP文件编辑器,通过这个编辑器可以编辑SP里面的内容,并将这些修改提交给SP。

adstract Map<String,?>

getAll()

从SP中查询出所有的 key-value。

adstract  boolean

getBoolean(String key,boolean defValue)

根据 key 从 SP 中查询对应的 boolean 值,如果查不到就返回默认值。

adstract  float

getFloat(String key,float defValue)

根据 key 从 SP 中查询对应的 float 值,如果查不到就返回默认值。

adstract  int

getInt(String key,int defValue)

根据 key 从 SP 中查询对应的 int 值,如果查不到就返回默认值。

adstract  long

getLong(String key,long defValue)

根据 key 从 SP 中查询对应的 long 值,如果查不到就返回默认值。

adstract  String

getString(String key,String defValue)

根据 key 从 SP 中查询对应的 String 值,如果查不到就返回默认值。

adstract  Set<String>

getStringSet(String key,Set<String> defValue)

根据 key 从 SP 中查询对应的一组 String 值,如果查不到就返回默认值。

adstract  void

registerOnSharedPreferencesChangeListener(SharedPreferences.OnSharedPreferencesChangeListener

  listener )

注册SP发生改变的监听回调

adstract  void

unregisterOnSharedPreferencesChangeListener(SharedPreferences.OnSharedPreferencesChangeListener

  listener )

取消SP发生改变的监听回调

  • SharedPreferences.Editor 接口的方法
adstract  void

apply()

将SP的修改返回给当前正在被编辑的SP。(异步提交,不保证数据完整性,如果你在apply() 未完成前调用commit(),则会造成commit()阻塞,直到apply()执行完成,才会执行commit(),如果你不在乎返回值的话,可以将 commit() 替换成 apply()。)

adstract  SharedPreferences.Editor

clear()

清空SP中的所有数据。

adstract  boolean

commit()

将SP的修改返回给当前正在被编辑的SP。(同步提交)

如果您不关心返回值并且正在从应用程序的主线程中使用它,请考虑使用apply()。

adstract  SharedPreferences.Editor

PutBoolean(String key,boolean value)

在SP编辑器中设置一个布尔值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

PutFloat(String key,float value)

在SP编辑器中设置一个float值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

PutInt(String key,int value)

在SP编辑器中设置一个int值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

PutLong(String key,long value)

在SP编辑器中设置一个long值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

PutString(String key,String value)

在SP编辑器中设置一个String值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

PutStringSet(String key,Set<String> value)

在SP编辑器中设置一组String值,一旦调用commit()或apply(),就会被写入。

adstract  SharedPreferences.Editor

remove(String key)

根据key,删除SP中的值。

至此SP的功能已经介绍完了。

我们接下来就看看具体的用法以及自己实现一个SPUtils。

  • 我们先动手封装一个SPUtils,这样大大减少了很多的模板代码,你也可以根据自己的业务自定义封装,以下是我封装的。
import android.content.Context;
import android.content.SharedPreferences;

import java.util.Map;

public class SPUtils {

    private final static String spName = "Test";

    public static void putValue(Context context, String key, Object value) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = sp.edit();
        if (value instanceof Boolean) {
            edit.putBoolean(key, (Boolean) value);
        } else if (value instanceof Float) {
            edit.putFloat(key, (Float) value);
        } else if (value instanceof Integer) {
            edit.putInt(key, (Integer) value);
        } else if (value instanceof Long) {
            edit.putLong(key, (Long) value);
        } else if (value instanceof String) {
            edit.putString(key, (String) value);
        }
        edit.apply();
    }

    public static Object getValue(Context context, String key, Object defValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        if (defValue instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defValue);
        } else if (defValue instanceof Float) {
            return sp.getFloat(key, (Float) defValue);
        } else if (defValue instanceof Integer) {
            return sp.getInt(key, (Integer) defValue);
        } else if (defValue instanceof Long) {
            return sp.getLong(key, (Long) defValue);
        } else if (defValue instanceof String) {
            return sp.getString(key, (String) defValue);
        }
        return null;
    }

    public static void clearSP(Context context) {
        context.getSharedPreferences(spName, Context.MODE_PRIVATE)
                .edit()
                .clear()
                .apply();
    }

    public static void removeSP(Context context, String Key) {
        context.getSharedPreferences(spName, Context.MODE_PRIVATE)
                .edit()
                .remove(Key)
                .apply();
    }
    
    public static Map<String, ?> getAllSP(Context context) {
        return context.getSharedPreferences(spName, Context.MODE_PRIVATE).getAll();
    }

}
  • 我们现在模拟登录页面保存账号密码的功能。我创建了两个button,一个用来存储账号密码,一个用来读取账号密码并且进行删除和清空操作。具体如下:
public class MainActivity extends AppCompatActivity {

    public static final String SP_USERNAME_KEY = "SP_USERNAME_KEY";
    public static final String SP_PASSWORD_KEY = "SP_PASSWORD_KEY";
    public static final String TAG = "Main_Activity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        findViewById(R.id.btn_put).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SPUtils.putValue(MainActivity.this, SP_USERNAME_KEY, "哈哈");
                SPUtils.putValue(MainActivity.this, SP_PASSWORD_KEY, 123456);
            }
        });

        findViewById(R.id.btn_get).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //1.首次正常获取
                Map<String, ?> allSP = SPUtils.getAllSP(MainActivity.this);
                int size = allSP.size();
                Log.d(TAG, "1.getAllSP.size() --> " + size);

                String username = (String) SPUtils.getValue(MainActivity.this, SP_USERNAME_KEY, "");
                int password = (int) SPUtils.getValue(MainActivity.this, SP_PASSWORD_KEY, -1);
                Log.d(TAG, "1.username --> " + username + " ,1.password --> " + password);

                //2.删除 SP_USERNAME_KEY 后,打印sp数量,以及数据情况
                SPUtils.removeSP(MainActivity.this, SP_USERNAME_KEY);

                Map<String, ?> allSP2 = SPUtils.getAllSP(MainActivity.this);
                int size2 = allSP2.size();
                Log.d(TAG, "2.getAllSP.size() --> " + size2);

                String username2 = (String) SPUtils.getValue(MainActivity.this, SP_USERNAME_KEY, "");
                int password2 = (int) SPUtils.getValue(MainActivity.this, SP_PASSWORD_KEY, -1);
                Log.d(TAG, "2.username --> " + username2 + " ,2.password --> " + password2);

                //清空sp后,打印sp数量,以及数据情况
                SPUtils.clearSP(MainActivity.this);

                Map<String, ?> allSP3 = SPUtils.getAllSP(MainActivity.this);
                int size3 = allSP3.size();
                Log.d(TAG, "3.getAllSP.size() --> " + size3);

                String username3 = (String) SPUtils.getValue(MainActivity.this, SP_USERNAME_KEY, "");
                int password3 = (int) SPUtils.getValue(MainActivity.this, SP_PASSWORD_KEY, -1);
                Log.d(TAG, "3.username --> " + username3 + " ,3.password --> " + password3);

            }
        });
    }
}
  • 此为Log输出信息:
D/Main_Activity: 1.getAllSP.size() --> 2
D/Main_Activity: 1.username --> 哈哈 ,1.password --> 123456
D/Main_Activity: 2.getAllSP.size() --> 1
D/Main_Activity: 2.username -->  ,2.password --> 123456
D/Main_Activity: 3.getAllSP.size() --> 0
D/Main_Activity: 3.username -->  ,3.password --> -1

至此SP的介绍以及使用就完毕了,希望对你有帮助。

欢迎加入Q群一起探讨Android问题。Q群:653123508。

猜你喜欢

转载自blog.csdn.net/TTAndroid/article/details/81386128