SharedPreferences 使用

1.context.getPreferences (int mode)

获取的是此Activity私有的Preference,以此Activity的名字命名,因此一个Activity只有一个,属于这个Activity。

保存在data/data/包名/shared_prefs位置下

public SharedPreferences getPreferences(int mode) {
    return getSharedPreferences(getLocalClassName(), mode);
}

2.context.getSharedPreferences (String name, int mode)

属于整个应用,可以有多个,以给定的name为文件名保存在系统中。
保存在data/data/包名/shared_prefs位置下

3.PreferenceManager.getDefaultSharedPreferences(context);

属于整个应用,只有一个,根据包名命名("包名"+"_preferences.xml")
其实也是调用context.getSharedPreferences (String name, int mode)
保存在data/data/包名/shared_prefs位置下
public static SharedPreferences getDefaultSharedPreferences(Context context) {
    return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
            getDefaultSharedPreferencesMode());
}

4.谨慎使用

SharedPreference将常驻内存,避免加载使用不到的,消耗内存
细分,将不常用与频繁使用的分开

ContextImpl中

private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;

public SharedPreferences getSharedPreferences(String name, int mode) {
    SharedPreferencesImpl sp;
    synchronized (ContextImpl.class) {
        if (sSharedPrefs == null) {
            sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
        }
        //根据包名进行一级分类
        final String packageName = getPackageName();
        ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
        if (packagePrefs == null) {
            packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
            sSharedPrefs.put(packageName, packagePrefs);
        }

        ........
        //当前包名,二级分类(具体SharedPreferences)
        sp = packagePrefs.get(name);
        if (sp == null) {
            File prefsFile = getSharedPrefsFile(name);
            //我们获取的就是SharedPreferences的实现类SharedPreferencesImpl
            sp = new SharedPreferencesImpl(prefsFile, mode);
            packagePrefs.put(name, sp);
            return sp;
        }
    }
    ............
    return sp;
}

SharedPreferencesImpl中

private Map<String, Object> mMap;
SharedPreferencesImpl(File file, int mode) {
    ..........
    mLoaded = false; //是否加载解析过
    mMap = null;    //键值对就是放这里
    startLoadFromDisk();
}


private void startLoadFromDisk() {
    synchronized (this) {
        mLoaded = false;
    }
    new Thread("SharedPreferencesImpl-load") {
        public void run() {
            synchronized (SharedPreferencesImpl.this) {
                loadFromDiskLocked();
            }
        }
    }.start();
}


private void loadFromDiskLocked() {
    if (mLoaded) {
        return;
    }
    ..........
    Map map = null;
    StructStat stat = null;
    try {
        stat = Libcore.os.stat(mFile.getPath());
        if (mFile.canRead()) {
            BufferedInputStream str = null;
            try {
                str = new BufferedInputStream(
                        new FileInputStream(mFile), 16*1024);
                map = XmlUtils.readMapXml(str); //读取到的数据放内存中(以键值对形式)
            } catch (XmlPullParserException e) {
                Log.w(TAG, "getSharedPreferences", e);
            } catch (FileNotFoundException e) {
                Log.w(TAG, "getSharedPreferences", e);
            } catch (IOException e) {
                Log.w(TAG, "getSharedPreferences", e);
            } finally {
                IoUtils.closeQuietly(str);
            }
        }
    } catch (ErrnoException e) {
    }
    mLoaded = true;//执行完后更换状态,下次不再重复加载
    if (map != null) {
        mMap = map;
        ........
    } else {
        mMap = new HashMap<String, Object>();
    }
    notifyAll();
}

获取值时

public int getInt(String key, int defValue) {
    synchronized (this) {
        awaitLoadedLocked();
        Integer v = (Integer)mMap.get(key);
        return v != null ? v : defValue;
    }
}
/**
 *如果SharedPreferences数据很多,那么首次解析,并紧跟着存取值时,主线程阻塞比较严重
 */
private void awaitLoadedLocked() {
   .......
    //上面创建SharedPreferencesImpl创建时,等loadFromDisk解析SharedPreference线程执行完后,才能跳过
    while (!mLoaded) {
        try {
            wait();//这里是主线程,阻塞了
        } catch (InterruptedException unused) {
        }
    }
}

阅读更多

没有更多推荐了,返回首页