getSharedPreferences()與getSharedPreferences()與getDefaultSharedPreferences()的區別

一直迷惑於這三個方法的關係,最近忙完項目,好好的分析一下。

如果你熟悉Context那麼你可能知道Context當中有這樣一個方法:(關於Context的說明)

一、getSharedPreferences(String name, int mode)

abstract SharedPreferences getSharedPreferences(String name, int mode)

Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.


得到名爲‘name’的偏好文件。同時你可以更改和返回他的值。任何調用者在調用同樣名字的偏好文件時只有一個實例返回,這就意味着這些調用者都可以看到其他調用者做出的更改。


這個函數的參數如下:

Parameters
   name:
  Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).

mode:
  Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE andMODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targetting Gingerbread (Android 2.3) and below, and off by default in later versions.

name爲本組件的配置文件名( 自己定義,也就是一個文件名),當這個文件不存在時,直接創建,如果已經存在,則直接使用,


mode爲操作模式,默認的模式爲0或MODE_PRIVATE,還可以使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE
mode指定爲MODE_PRIVATE,則該配置文件只能被自己的應用程序訪問。
mode指定爲MODE_WORLD_READABLE,則該配置文件除了自己訪問外還可以被其它應該程序讀取。
mode指定爲MODE_WORLD_WRITEABLE,則該配置文件除了自己訪問外還可以被其它應該程序讀取和寫入

二、PreferenceManager的方法getSharedPreferences()

這個方法我們可以通過查看其源碼:

             /** 
  1.     * Gets a SharedPreferences instance that preferences managed by this will 
  2.     * use. 
  3.     *  
  4.     * @return A SharedPreferences instance pointing to the file that contains 
  5.     *         the values of preferences that are managed by this. 
  6.     */  
  7.    public SharedPreferences getSharedPreferences() {  
  8.        if (mSharedPreferences == null) {  
  9.            mSharedPreferences = mContext.getSharedPreferences(mSharedPreferencesName,  
  10.                    mSharedPreferencesMode);  
  11.        }  
  12.          
  13.        return mSharedPreferences;  
  14.    }  
 /**
     * Gets a SharedPreferences instance that preferences managed by this will
     * use.
     * 
     * @return A SharedPreferences instance pointing to the file that contains
     *         the values of preferences that are managed by this.
     */
    public SharedPreferences getSharedPreferences() {
        if (mSharedPreferences == null) {
            mSharedPreferences = mContext.getSharedPreferences(mSharedPreferencesName,
                    mSharedPreferencesMode);
        }
        
        return mSharedPreferences;
    }

這個方法是一個普通的方法,必須有PreferenceManager的實例調用才行,因此我們再按圖索驥找找其構造方法。

  1. /** 
  2.     * This constructor should ONLY be used when getting default values from 
  3.     * an XML preference hierarchy. 
  4.     * <p> 
  5.     * The {@link PreferenceManager#PreferenceManager(Activity)} 
  6.     * should be used ANY time a preference will be displayed, since some preference 
  7.     * types need an Activity for managed queries. 
  8.     */  
  9.    private PreferenceManager(Context context) {  
  10.        init(context);  
  11.    }  
  12.   
  13.    private void init(Context context) {  
  14.        mContext = context;  
  15.          
  16.        setSharedPreferencesName(getDefaultSharedPreferencesName(context));  
  17.    }  
 /**
     * This constructor should ONLY be used when getting default values from
     * an XML preference hierarchy.
     * <p>
     * The {@link PreferenceManager#PreferenceManager(Activity)}
     * should be used ANY time a preference will be displayed, since some preference
     * types need an Activity for managed queries.
     */
    private PreferenceManager(Context context) {
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        
        setSharedPreferencesName(getDefaultSharedPreferencesName(context));
    }

  1. /** 
  2.      * Sets the name of the SharedPreferences file that preferences managed by this 
  3.      * will use. 
  4.      *  
  5.      * @param sharedPreferencesName The name of the SharedPreferences file. 
  6.      * @see Context#getSharedPreferences(String, int) 
  7.      */  
  8.     public void setSharedPreferencesName(String sharedPreferencesName) {  
  9.         mSharedPreferencesName = sharedPreferencesName;  
  10.         mSharedPreferences = null;  
  11.     }  
/**
     * Sets the name of the SharedPreferences file that preferences managed by this
     * will use.
     * 
     * @param sharedPreferencesName The name of the SharedPreferences file.
     * @see Context#getSharedPreferences(String, int)
     */
    public void setSharedPreferencesName(String sharedPreferencesName) {
        mSharedPreferencesName = sharedPreferencesName;
        mSharedPreferences = null;
    }

  1. private static String getDefaultSharedPreferencesName(Context context) {  
  2.        return context.getPackageName() + "_preferences";  
  3.    }  
 private static String getDefaultSharedPreferencesName(Context context) {
        return context.getPackageName() + "_preferences";
    }

由以上方法,我們可以知道,最終我們調用getSharedPreferences()方法得到的是一個名爲”yourpackageName_preferences“的偏好。同時其mode爲默認私有。

三、getDefaultSharedPreferences方法

  1. /** 
  2.     * Gets a SharedPreferences instance that points to the default file that is 
  3.     * used by the preference framework in the given context. 
  4.     *  
  5.     * @param context The context of the preferences whose values are wanted. 
  6.     * @return A SharedPreferences instance that can be used to retrieve and 
  7.     *         listen to values of the preferences. 
  8.     */  
  9.    public static SharedPreferences getDefaultSharedPreferences(Context context) {  
  10.        return context.getSharedPreferences(getDefaultSharedPreferencesName(context),  
  11.                getDefaultSharedPreferencesMode());  
  12.    }  
  13.   
  14.    private static String getDefaultSharedPreferencesName(Context context) {  
  15.        return context.getPackageName() + "_preferences";  
  16.    }  
  17.   
  18.    private static int getDefaultSharedPreferencesMode() {  
  19.        return Context.MODE_PRIVATE;  
  20.    }  
 /**
     * Gets a SharedPreferences instance that points to the default file that is
     * used by the preference framework in the given context.
     * 
     * @param context The context of the preferences whose values are wanted.
     * @return A SharedPreferences instance that can be used to retrieve and
     *         listen to values of the preferences.
     */
    public static SharedPreferences getDefaultSharedPreferences(Context context) {
        return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
                getDefaultSharedPreferencesMode());
    }

    private static String getDefaultSharedPreferencesName(Context context) {
        return context.getPackageName() + "_preferences";
    }

    private static int getDefaultSharedPreferencesMode() {
        return Context.MODE_PRIVATE;
    }

這個方法是靜態的,因此可以直接調用,同時它與我們調用getSharedPreferences()方法得到的返回值是一樣的,只是調用的方式不同罷了。

四、SharedPreferences到底是什麼

它是一個輕量級的存儲類,特別適合用於保存軟件配置參數。使用SharedPreferences保存數據,其背後是用xml文件存放數據,文件存放在/data/data/<package name>/shared_prefs目錄下:

  1. SharedPreferences sharedPreferences = getSharedPreferences("TEST", Context.MODE_PRIVATE);  
  2. Editor editor = sharedPreferences.edit();//獲取編輯器   
  3. editor.putString("name""Yang");  
  4. editor.putInt("sex""boy");  
  5. editor.commit();//提交修改  
SharedPreferences sharedPreferences = getSharedPreferences("TEST", Context.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();//獲取編輯器
editor.putString("name", "Yang");
editor.putInt("sex", "boy");
editor.commit();//提交修改
生成的TEST.xml文件內容如下:
  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>  
  2. <map>  
  3. <string name="name">Yang</string>  
  4. <int name="sex">boy</string>  
  5. </map>  
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="name">Yang</string>
<int name="sex">boy</string>
</map>

因爲SharedPreferences背後是使用xml文件保存數據,getSharedPreferences(name,mode)方法的第一個參數用於指定該文件的名稱,名稱不用帶後綴,後綴會由Android自動加上。方法的第二個參數指定文件的操作模式,共有四種操作模式,這四種模式前面介紹使用文件方式保存數據時已經講解過。如果希望SharedPreferences背後使用的xml文件能被其他應用讀和寫,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE權限。
另外Activity還提供了另一個getPreferences(mode)方法操作SharedPreferences,這個方法默認使用當前類不帶包名的類名作爲文件的名稱。

如果訪問其他應用中的Preference,前提條件是:該preference創建時指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE權限。如:有個<package name>爲cn.yang.action的應用使用下面語句創建了preference。
getSharedPreferences("TEST", Context.MODE_WORLD_READABLE);
其他應用要訪問上面應用的preference,首先需要創建上面應用的Context,然後通過Context 訪問preference ,訪問preference時會在應用所在包下的shared_prefs目錄找到preference :
Context otherAppsContext = createPackageContext("cn.yang.action", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("TEST", Context.MODE_WORLD_READABLE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("sex", "");


如果不通過創建Context訪問其他應用的preference,也可以以讀取xml文件方式直接訪問其他應用preference對應的xml文件,如: 
File xmlFile = new File(“/data/data/<package name>/shared_prefs/itcast.xml”);//<package name>應替換成應用的包名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章