1. 程式人生 > >Android面試一天一題(14 Day:SharedPreferences)

Android面試一天一題(14 Day:SharedPreferences)

如果說程式可以簡單理解成“指令和資料的集合”,那麼你在任何平臺上程式設計都難以離開資料儲存,在Android平臺上自然也不會例外。說到資料的儲存,對於Key-Value對應的資料存取,Android提供SharedPreferences的方式可以進行方便的操作。大家也都覺得它的使用很簡單,但是有時候簡單的地方也會發生問題,而且你很難查覺到問題根源在這個地方。

面試題:修改SharedPreferences後兩種提交方式有什麼區別?

SharedPreferences類是一個介面類,真正的實現類是SharedPreferencesImpl。修改SharedPreferences需要獲取它的Editor,在對Editor進行put操作後,最後通過commit或者apply提交修改到記憶體和檔案。當然有了兩種都可以提交的方法,肯定要區別一下的。從實現類SharedPreferencesImpl的

原始碼上看也很容易看出兩者的區別:

commit這種方式很常用,在比較早的SDK版本中就有了,這種提交修改的方式是同步的,會阻塞呼叫它的執行緒,並且這個方法會返回boolean值告知儲存是否成功(如果不成功,可以做一些補救措施)。
而apply是非同步的提交方式,目前Android Studio也會提示大家使用這種方式。

還有一點用得比較少的,就是SharedPreferences還提供一個監聽介面可以監聽SharedPreferences的鍵值變化,需要監控鍵值變化的可以用registerOnSharedPreferenceChangeListener新增監聽器。

public
interface SharedPreferences { /** * Interface definition for a callback to be invoked when a shared * preference is changed. */ public interface OnSharedPreferenceChangeListener { void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key); }

多程序操作和讀取SharedPreferences的問題

前段時間,專案組裡發現一個偶現的問題,從Http明明獲取了正確的資料儲存到SharedPreferences,但立即再從SharedPreferences讀取這個值時發現是初始值。開始大家一直把精力放在Http的請求上,最後才發現是SharedPreferences多程序間資料共享會導致的問題。

在SDK 3.0及以上版本,可以通過Context.MODE_MULTI_PROCESS屬性來實現SharedPreferences多程序共享。如下設定:

    public static SharedPreferences getSharedPreferences(String name) {
        if (null != context) {
            if (Build.VERSION.SDK_INT >= 11) {
                return context.getSharedPreferences(name, Context.MODE_MULTI_PROCESS);
            } else {
                return context.getSharedPreferences(name, Context.MODE_PRIVATE);
            }
        }

        return null;
    }

本來以為通過MODE_MULTI_PROCESS屬性使用SharedPreferences就可以實現不同時程間共享資料,但是在真正使用中確發現有會有一定概率出現這個取值出錯(變為初始值)問題。

最後發現在官網上Google也在SDK 6.0的版本將這個MODE_MULTI_PROCESS標識為deprecated(不贊成使用)。目前來說,越來越多的專案在不斷的膨脹,為了降低單個程序的記憶體佔用率,使用”android:process”配置一些元件在單獨的程序中執行已經是司空見慣了,所以大家在遇到自己的專案有多程序時,要注意一下SharedPreferences的問題。

小結

在一個程序中,SharedPreference往往建單個例項就可以了,一般不會出現併發衝突,如果對提交的結果不關心的話,建議使用apply,當然需要確保提交成功且有後續操作的話,還是需要用commit的。

因為SharedPreferences在多程序方面的問題,大家也可以思考下能不能自己實現一個加強版的SharedPreferences解決這些問題,網上也有一些開源的替代方案,如Github上的tray。(建議大家先想一下,再看這個專案。)