Android SharedPreferences 使用方法详解

目录

1. SharedPreferences 定义介绍

2. SharedPreferences.Editor 方法介绍

2.1 apply()

2.2 commit()

2.3 clear()

2.4 remove()

2.5 apply() 与 commit() 的区别

3. SharedPreferences 例子Demo

 3.1 getPreferences() 例子Demo

3.2 getSharedPreferences() 例子Demo

3.3 getDefaultSharedPreferences() 例子Demo

4. getPreferences() getSharedPreferences() 及 getDefaultSharedPreferences() 三者区别


1. SharedPreferences 定义介绍

用于访问和修改 context#getSharedPreferences 返回的 preference 数据的接口,如果你想要保存的键值(key-value)集合,且数据量相对较小,这时候使用 SharedPreferences 存储数据比较合适。对 Preference 数据进行修改时必须通过 Editor 对象,以确保 Preference 数据处于一致的状态,并将它们提交到存储中( /data/data/包名/shared_prefs/ )进行控制。

2. SharedPreferences.Editor 方法介绍

用来修改 SharedPreferences 对象值的接口,修改完毕,调用 commit() 或 apply() 方法来提交生效刚所做的修改。

2.1 apply()

void apply(); 没有返回值

异步提交你的改变,来替换当前 SharedPreferences 对象中的任何内容。

注意:如果有两个 Editor 对象同时在修改同一个 Preferences 对象,两个 Editor 谁提交的晚,那么谁的提交有效,也就是说,后面的提交会覆盖之前的提交

2.2 commit()

boolean commit(); 当新的值成功的存入本地数据库时,返回 true。

同步提交你的改变,来替换当前 SharedPreferences 对象中的任何内容。

注意:如果有两个 Editor 同时修改同一个 preferences 对象,最后一个调用 commit() 方法的 Editor 获胜,其所做的改变生效

当你不需要关心其返回值并且是在 app 的主线程中使用它时,使用 apply() 方法会更加合适。

2.3 clear()

Editor clear(); 返回 SharedPreferences.Editor 对象

删除 Preferences 中的所有值,因为返回 SharedPreferences.Editor 对象,所以可以将 Editor 的调用方法链接起来使用,比如先 put,然后 clear,再 put:

mEditor.putString("firstAdd", "first add by jere\n")
        .clear()
        .putString("secondAdd", "second add by jere !")
        .apply();

思考一下,执行完该语句,SharedPrefeences 里存取了什么数据?答案见下图:

原因: 在 SharedPreferencers 提交改变之前,无论是在 put 数据方法之前或之后调用 clear() 方法,都会优先执行 clear() 方法。

2.4 remove()

Editor remove(String key); 返回 SharedPreferences.Editor 对象

删除单个指定 key 的 preferences 值,跟 clear() 方法一样,因为返回 SharedPreferences.Editor 对象,所以可以将 Editor 的调用方法链接起来使用。比如接着上方 clear() 的例子,删除“firstAdd”的数据,效果如下所示:

public class FirstActivity extends AppCompatActivity implements View.OnClickListener {
    private SharedPreferences mSp;
    private SharedPreferences.Editor mEditor;

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

        mSp = getSharedPreferences("PreferencesName", Context.MODE_PRIVATE);
        mEditor = mSp.edit();

        Button setBtn = findViewById(R.id.set_btn);
        Button removeBtn = findViewById(R.id.remove_btn);
        Button getBtn = findViewById(R.id.get_btn);
        setBtn.setOnClickListener(this);
        removeBtn.setOnClickListener(this);
        getBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.set_btn:
                mEditor.putString("firstAdd", "first add by jere\n")
                        .clear()
                        .putString("secondAdd", "second add by jere !")
                        .apply();
                break;
            case R.id.remove_btn:
                mEditor.remove("firstAdd").apply();
                break;
            case R.id.get_btn:
                String firstAddString = mSp.getString("firstAdd", "");
                String secondAddStrig = mSp.getString("secondAdd", "");
                String displayString = firstAddString + secondAddStrig;
                TextView displayTv = findViewById(R.id.display_tv);
                displayTv.setText(displayString);
                break;
            default:
                break;
        }
    }
}

2.5 apply() 与 commit() 的区别

commit() 同步写入本地数据库,apply() 会先将改变提交到内存中的 SharedPreferences 中,然后在异步写入本地数据库,即使存入失败了也不会通知你。

特殊情况:当 SharedPreferences 正在执行一个 Editor 的 apply() 操作时,另一个 Editor 对此 SharedPreferences 执行 commit() 操作,这种情况下,因为 apply() 操作还没结束,所以 commit() 操作将被 block 阻止掉,直到 apply() 操作完成。

//所以正确的使用 commit() 方法为:如果 commit 不成功,提醒我们。
if (!editor.commit()) { 
	Log.e(LOG_TAG, "Failed to commit setting changes"); 
} 

3. SharedPreferences 例子Demo

三种方法创建 SharedPreferences 对象,分别是getSharedPreferences(int mode)、getSharedPreferences(String name, int mode)、getDefaultSharedPreferences(Context context) 三种方法,如下所示:

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.get_pref_btn:
            //getPreferences() 方法
            SharedPreferences sp = getPreferences(MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.putString("JereTest", "first test");
            editor.apply();
            break;
        case R.id.get_shared_pref_btn:
            //getSharedPreferences() 方法
            SharedPreferences sp1 = getSharedPreferences("testGetSharedPref", MODE_PRIVATE);
            SharedPreferences.Editor editor1 = sp1.edit();
            editor1.putString("getSharedPref", "test getSharedPreferences!");
            editor1.apply();
            break;
        case R.id.get_default_shared_pref_btn:
            //getDefaultSharedPreferences() 方法
            SharedPreferences sp2 = PreferenceManager.getDefaultSharedPreferences(this);
            SharedPreferences.Editor editor2 = sp2.edit();
            editor2.putString("getDefaultSp", "jere test getDefaultSharedPreferences!");
            editor2.apply();
            Intent intent = new Intent(this, SecondActivity.class);
            startActivity(intent);
            break;
        default:
            break;
    }
}

SharedPreferences的操作模式(MODE),一般都用Context.MODE_PRIVATE。

Context.MODE_PRIVATE为默认操作模式,其中创建的文件只能被调用应用程序访问,既只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
Context.MODE_APPEND模式会检查文件是否存在,存在就往文件末尾追加内容而不是覆盖,否则就创建新文件。

Context.MODE_WORLD_READABLE

Context.MODE_WORLD_WRITEABLE

自API level 17就已经弃用,从Android 7.0 (API level 24)开始,如果使用,Android会抛出SecurityException异常。如果您的应用程序需要与其他应用程序共享私有文件,它可以使用带有FLAG_GRANT_READ_URI_PERMISSION的FileProvider。

 

 

 

 

 

 

 3.1 getPreferences() 例子Demo

如果只需要为一个 Activity 使用一个共享首选项文件(shared preference file),直接在 Activity 中使用 Activity.getPreferences(int mode)。

//因为这将是用于该 Activity 的唯一首选项文件,所以无需提供名称。
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);

存储的文件将以 Activity 的类名及 xml 格式保存在 /data/data/包名/shared_prefs/ 下,例如:

例子:在同一个activity下进行保存/读取显示数据,同时尝试在不同的 activity 下读取数据。效果如下:

详细代码:

//on MainActivity
//save data 
mSetSharedPreferencesButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SharedPreferences sharedPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putString(NAME, mEditText.getText().toString());
        editor.apply();
    }
});

//retrieve data and display
getSpButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SharedPreferences sharedPref = MainActivity.this.getPreferences(Context.MODE_PRIVATE);
        String nameString = sharedPref.getString(NAME, "test by null");
        displaySpText.setText(nameString);
    }
});
//on SecondActivity
//retrieve data in second activity, the default value is null
SharedPreferences sharedPref = this.getPreferences(Context.MODE_PRIVATE);
contentString = sharedPref.getString(NAME, "null");

// display data
mSharedPreferencesButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mTextView.setText(contentString);
        mTextView.setVisibility(View.VISIBLE);
    }
});

3.2 getSharedPreferences() 例子Demo

当你想要保存或检索的数据可以在应用程序中的不同的 Activity 中使用时,或需要通过名称标识多个共享首选项文件时(shared preference file),使用 Context.getSharedPreferences(String name, int mode),可以使用第一个参数指定这些文件。你可以从应用程序的任何Context调用它。

SharedPreferences sharedPref = context.getSharedPreferences("file name", Context.MODE_PRIVATE);

存储的文件将以我们提供的文件并以 xml 格式保存在 /data/data/包名/shared_prefs/ 下,例如我们提供的文件名为“testGetSharedPref”:

例子:两个 activity 之间进行存/取数据,实现数据共享,在MainActivity 中存储文件“testGetSharedPref”,然后跳到 SecondActivity 中读取该文件中的内容,然后显出出来,效果图如下:

详细代码:

//在 MainActivity 中存储数据,文件名为“testGetSharedPref”:
SharedPreferences sharedPref = this.getSharedPreferences("testGetSharedPref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(NAME, "My name is Jere!");
editor.putString(HOBBY, "I like play basketball!");
editor.apply();

mSetSharedPreferencesButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //存储“testGetSharedPref”文件后,跳转到 SecondActivity
        Intent secondIntent = new Intent(MainActivity.this, SecondActivity.class);
        startActivity(secondIntent);
    }
});
//在 SecondActivity 中取出 "testGetSharedPref" 文件中的数据并显示出来:
SharedPreferences sharedPref = this.getSharedPreferences("testGetSharedPref", Context.MODE_PRIVATE);
String nameString = sharedPref.getString(NAME, null);
String hobbyString = sharedPref.getString(HOBBY, null);
contentString = nameString + "\n" + hobbyString;

mSharedPreferencesButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mTextView.setText(contentString);
        mTextView.setVisibility(View.VISIBLE);
    }
});

3.3 getDefaultSharedPreferences() 例子Demo

可以获得整个应用程序的默认共享首选项文件,通过调用静态方法 PreferenceManager.getDefaultSharedPreferences() 将共享首选项文件保存在应用程序任何 Actiity 都可以访问的位置中。

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");

我们不需要额外提供文件名,所存储的文件以我们 App 的包名加 _preferences 并以 xml 的格式保存在 /data/data/包名/shared_prefs/ 下,例如:我们的包名为com.jere.test

实践:EditText() 输入数据,点击set SharedPreferences按钮,保存数据,并且跳转到第二个页面;在第二个页面点就get SharedPreferences按钮,取得数据,并显示出来!效果图如下?:

详细代码如下:

//在 MainActivity 中保存文件
SharedPreferences sp2 = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor2 = sp2.edit();
editor2.putString("getDefaultSp", "jere test getDefaultSharedPreferences!");
editor2.apply();
//然后跳转到 SecondActivity
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
//在 SecondActivity 中读取文件内容并且显示出来
public class SecondActivity extends AppCompatActivity {

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

        Button btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(SecondActivity.this);
                String contentData = sp.getString("getDefaultSp", null);

                TextView tv = findViewById(R.id.show_tv);
                tv.setText(contentData);
            }
        });
    }
}

4. getPreferences() getSharedPreferences() 及 getDefaultSharedPreferences() 三者区别

虽然三种方法创建的文件都是以 xml 的格式存储在 /data/data/包名/shared_prefs/ 下,但其文件名还是有很大区别的,如下图所示:

  1. 1号文件由 Activity.getPreferences(int mode) 方法创建,存储的文件以 Activity 名字(Java 类名不带后缀)命名。
  2. 2号文件由 PreferenceManager.getDefaultSharedPreferences(Context context) 方法创建,存储的文件以 App 的包名加上 _preferences 命名。
  3. 3号文件由  Context.getSharedPreferences(String name, int mode) 方法创建,存储的文件以传入的 name 参数命名。

getPreferences() 只能在当前页面(同一个activity)之间进行数据存取,若想在多个 activity 中共享数据,需要使用getSharedPreferences() 或 getDefaultSharedPreferences()。

 

END~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值