在偏好檔案中儲存資料,偏好檔案儲存體資料

來源:互聯網
上載者:User

在偏好檔案中儲存資料,偏好檔案儲存體資料

SharedPreferences對象使用常規的XML檔案來儲存資料,這些檔案儲存體在應用程式的資料目錄內。該XML檔案的結構很簡單,因為它只允許儲存鍵/值對,不過Android API還提供了非常方便的抽象,允許開發人員以型別安全的方式讀寫資料。

建立SharedPreferences對象最簡單的方式是使用PreferenceManager.getDefaultSharedPreferences()方法,它會返回應用程式預設的偏好對象。使用該方式來儲存主要的喜好設定很方便,因為架構會自動管理好檔案名稱。但是,如果應用程式有多個偏好檔案,最好使用Context.getSharedPreference()方法,它允許開發人員自由地命名檔案。如果只是建立和Activity相關的偏好檔案,可以使用Activity.getPreference()方法,它會在調用時得到Activity的名字。

PreferenceManager.getDefaultSharedPreferences()建立的偏好檔案名稱是由包名以及尾碼_preferences組成的,如com.liyuanjinglyj.code_preferences。雖然很少需要這個名字,但如果要實現檔案備份代理該名字就很重要。

SharedPreferences支援的儲存值的類型有int,float.long.boolean,String以及set<String>對象。鍵名必須是一個有效字串,常見的做法是使用點符號按組結構化多個鍵值。

例如,如果偏好檔案包含用於網路設定以及使用者介面設定相關的值,可以通過為每個鍵添加network或者ui首碼來把它們分組。通過該方式,開發人員可以輕鬆的管理鍵/值對,避免命名衝突。下面的例子示範了如何通過使用首碼並在單獨的Java介面檔案中定義鍵來結構化偏好資料:

public interface Constants {    public static final String NETWORK_PREFIX = "network.";    public static final String UI_PREFIX = "ui.";    public static final String NETWORK_RETRY_COUNT            = NETWORK_PREFIX + "retryCount";    public static final String NETWORK_CONNECTION_TIMEOUT            = NETWORK_PREFIX + "connectionTimeout";    public static final String NETWORK_WIFI_ONLY            = NETWORK_PREFIX + "wifiOnly";    public static final String UI_BACKGROUND_COLOR            = UI_PREFIX + "backgroundColor";    public static final String UI_FOREGROUND_COLOR            = UI_PREFIX + "foregroundColor";    public static final String UI_SORT_ORDER            = UI_PREFIX + "sortOrder";    public static final int SORT_ORDER_NAME = 10;    public static final int SORT_ORDER_AGE = 20;    public static final int SORT_ORDER_CITY = 30;}

推薦使用上面的方法訪問儲存的偏好值,而不是把鍵名寫入程式碼在代碼中。這樣做可以避免誤拼字,從而減少由於拼字導致的bug。

下面的代碼示範了使用之前定義的Constants類來訪問偏好檔案:

private void readUiPreferences() {    SharedPreferences preferences            = PreferenceManager.getDefaultSharedPreferences(this);    int defaultBackgroundColor = getResources().            getColor(R.color.default_background);    int backgroundColor = preferences.getInt(            Constants.UI_BACKGROUND_COLOR,            defaultBackgroundColor);    View view = findViewById(R.id.background_view);    view.setBackgroundColor(backgroundColor);}

要修改儲存在偏好檔案中的值,首先需要擷取Editor執行個體,它提供了相應的PUT方法,以及用於提交修改的方法。在Android2.3之前,通過使用commit()方法把修改同步提交到存放裝置中。但在2.3版本中,Editor提供了用於非同步執行寫操作的apply()方法。因為要儘可能地避免在主線程執行阻塞的操縱,apply()方法比之前的commit()方法更好。這使得在主線程直接從UI操作更新SharedPreferences很安全。

public void doToggleWifiOnlyPreference(View view) {    SharedPreferences preferences = PreferenceManager.            getDefaultSharedPreferences(this);    boolean currentValue = preferences.            getBoolean(Constants.NETWORK_WIFI_ONLY, false);    preferences.edit()            .putBoolean(Constants.NETWORK_WIFI_ONLY, !currentValue)            .apply();}

上面的代碼顯示了使用點擊監聽器來切換儲存在Constants.NETWORK_WIFI_ONLY中的偏好值。如果使用之前的commit()方法,主線程可能會被阻塞,導致使用者體驗差。使用apply()方法就不需要擔心上面的問題。

在同一個進程中,每個偏好檔案都只有執行個體。所以即便從二個不同的組件使用相同的名字擷取二個SharedPreference對象,它實際上還是共用同一個執行個體,所以對於一個對象的改變會立即影響到另一個對象。

為了能在偏好值被修改的時候收到通知,開發人員需要註冊一個監聽器回呼函數,每當調用apply()或者commit()方法時都會觸發該監聽器回呼函數。最常見的例子是,在Activity中修改偏好值應該影響後台Service的行為,如下所示:

public class NetworkService extends IntentService        implements SharedPreferences.OnSharedPreferenceChangeListener {    public static final String TAG = "NetworkService";    private boolean mWifiOnly;    public NetworkService() {        super(TAG);    }    @Override    public void onCreate() {        super.onCreate();        SharedPreferences preferences = PreferenceManager                .getDefaultSharedPreferences(this);        preferences.registerOnSharedPreferenceChangeListener(this);        mWifiOnly = preferences.getBoolean(Constants.NETWORK_WIFI_ONLY,                false);    }    @Override    protected void onHandleIntent(Intent intent) {        ConnectivityManager connectivityManager                = (ConnectivityManager)                getSystemService(CONNECTIVITY_SERVICE);        NetworkInfo networkInfo                = connectivityManager.getActiveNetworkInfo();        int type = networkInfo.getType();        if (mWifiOnly && type != ConnectivityManager.TYPE_WIFI) {            Log.d(TAG, "只執行WIFI網路");            return;        }        performNetworkOperation(intent);    }    @Override    public void onSharedPreferenceChanged(SharedPreferences preferences,                                          String key) {        if (Constants.NETWORK_WIFI_ONLY.equals(key)) {            mWifiOnly = preferences                    .getBoolean(Constants.NETWORK_WIFI_ONLY, false);            if(mWifiOnly) {                cancelNetworkOperationIfNecessary();            }        }    }    @Override    public void onDestroy() {        super.onDestroy();        SharedPreferences preferences = PreferenceManager                .getDefaultSharedPreferences(this);        preferences.unregisterOnSharedPreferenceChangeListener(this);    }    private void cancelNetworkOperationIfNecessary() {        // 取消網路操作。    }    private void performNetworkOperation(Intent intent) {        // 連上網路操作    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.