**

一、SharedPreference简单使用

**
问题:
1.如果两个activity都使用同一个sharedpreference,但是第一个activity没有提交,第二个activity提交了,那么会出现什么结果。

2.不同的进程是否可以共享同一个sharedpreference

mode:
Context.MODE_PRIVATE:只被本地程序读写
Context.MODE_WORLD_READABLE:能被其他程序读
Context:MODE_WORLD_WRITEABLE:能被其他程序读、写

SPActivity:

Button mButtonStorage = (Button) findViewById(R.id.btn_storage);mButtonStorage.setOnClickListener(v -> {SharedPreferences sp = getPreferences(MODE_PRIVATE); //这是Activity特有的方法,只是当前activity使用,其他的activity使用不了Log.i(TAG,sp.getString("key","123"));SharedPreferences.Editor edit = sp.edit();edit.putString("key","key");Log.i(TAG,sp.getString("key","123"));Intent intent = new Intent(SPActivity.this, SPTargetActivity.class);startActivity(intent);});

SPTargetActivity:

Button mButtonStorage = (Button) findViewById(R.id.btn_storage);mButtonStorage.setOnClickListener(v -> {SharedPreferences sp = getPreferences(MODE_PRIVATE);SharedPreferences.Editor edit = sp.edit();edit.putString("key","value");edit.apply();Log.i(TAG,sp.getString("key","123"));});

结果
显示从SP到SPTarget,然后返回SP过程中的结果

结果说明:两个Activity不是在同一个Sharedpreference文件进行操作

SPActivity:

Button mButtonStorage = (Button) findViewById(R.id.btn_storage);mButtonStorage.setOnClickListener(v -> {// SharedPreferences sp = getPreferences(MODE_PRIVATE);SharedPreferences sp1 = getSharedPreferences("123",MODE_PRIVATE);//获取应用目录下的sp,应用内可以共享Log.i(TAG,sp1.getString("key","123"));SharedPreferences.Editor edit = sp1.edit();edit.putString("key","key");Log.i(TAG,sp1.getString("key","123"));Intent intent = new Intent(SPActivity.this, SPTargetActivity.class);startActivity(intent);});

SPTargetActivity:

Button mButtonStorage = (Button) findViewById(R.id.btn_storage);mButtonStorage.setOnClickListener(v -> {// SharedPreferences sp = getPreferences("",MODE_PRIVATE);SharedPreferences sp1 = getSharedPreferences("123",MODE_PRIVATE);SharedPreferences.Editor edit = sp1.edit();edit.putString("key","value");edit.apply();Log.i(TAG,sp1.getString("key","123"));});

结果
显示从SP到SPTarget,然后返回SP过程中的结果

结果说明:两个activity处理的是同一个文件,而且后一个Editor才是有效果的,SPActivity中的Editor并没有起作用,数据没有提交。

**

二、源码解析:

**

/**  #通过 Context.getSharedPreference(),获取对象。在所有客户端中,Sharedpreference是单例的。  #修改Sharedpreference必须通过提供的Editor接口,确保value值持久化存储。  #获取数据通过get()方法获取。* #

Note: 不能用于多线程中.** <div class="special reference">*

Developer Guides

*

For more information about using SharedPreferences, read the* "{@docRoot}guide/topics/data/data-storage.html#pref">Data Storage* developer guide.

div
>** @see Context#getSharedPreferences*/public interface SharedPreferences { /** * Interface definition for a callback to be invoked when a shared * preference is changed. 回调接口监听器 */ public interface OnSharedPreferenceChangeListener { /** * Called when a shared preference is changed, added, or removed. This * may be called even if a preference is set to its existing value. * *

This callback will be run on your main thread. * * @param sharedPreferences The {@link SharedPreferences} that received * the change. * @param key The key of the preference that was changed, added, or * removed. */ void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key); } /** #用于修改Sharedpreference中的值。但是所有的修改的值,必须在调用方法commit 或者 apply方法之后才能成功修改 */ public interface Editor { /** * Set a String value in the preferences editor, to be written back once * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. Passing {@code null} * for this argument is equivalent to calling {@link #remove(String)} with * this key. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putString(String key, @Nullable String value); /** * Set a set of String values in the preferences editor, to be written * back once {@link #commit} or {@link #apply} is called. * * @param key The name of the preference to modify. * @param values The set of new values for the preference. Passing {@code null} * for this argument is equivalent to calling {@link #remove(String)} with * this key. * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putStringSet(String key, @Nullable Set values); /** * Set an int value in the preferences editor, to be written back once * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putInt(String key, int value); /** * Set a long value in the preferences editor, to be written back once * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putLong(String key, long value); /** * Set a float value in the preferences editor, to be written back once * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putFloat(String key, float value); /** * Set a boolean value in the preferences editor, to be written back * once {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putBoolean(String key, boolean value); /** * Mark in the editor that a preference value should be removed, which * will be done in the actual preferences once {@link #commit} is * called. #标记key对应的记录应该被删除,但是必须在commit执行之后才能删除数据 * *

Note that when committing back to the preferences, all removals * are done first, regardless of whether you called remove before * or after put methods on this editor. #当执行commit方法,提交的时候,所有之前标记删除的操作都会先执行,无论是在put存数据之前还是之后是否执行了。也就是说,删除操作都会先执行,和删除的代码在哪里没关系。 * * @param key The name of the preference to remove. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor remove(String key); /** * Mark in the editor to remove all values from the * preferences. Once commit is called, the only remaining preferences * will be any that you have defined in this editor. #在editor标记中,删除所有数据。一旦提交,剩下的首选项将是您在这个编辑器中定义的任何参数 * *

Note that when committing back to the preferences, the clear * is done first, regardless of whether you called clear before * or after put methods on this editor. #和删除操作一样,清空操作都会先执行 * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor clear(); /** * Commit your preferences changes back from this Editor to the * {@link SharedPreferences} object it is editing. This atomically * performs the requested modifications, replacing whatever is currently * in the SharedPreferences. #从Editor中提交变化到正在修改的Sharedpreference中。这是自动执行的修改,无论是否在当前的Sharedpreference中,都会进行替换 * *

Note that when two editors are modifying preferences at the same * time, the last one to call commit wins. #当两个Editor同时修改preference的时候,后一个执行的才有效 * *

If you don't care about the return value and you're * using this from your application's main thread, consider * using {@link #apply} instead. #如果不关心返回值,而且是在主线程中操作的,可以考虑使用apply方法 * * @return Returns true if the new values were successfully written * to persistent storage. */ boolean commit(); /** * Commit your preferences changes back from this Editor to the * {@link SharedPreferences} object it is editing. This atomically * performs the requested modifications, replacing whatever is currently * in the SharedPreferences. # 从Editor中提交变化到正在修改的Sharedpreference中。这是自动执行的修改,无论是否在当前的Sharedpreference中,都会进行替换 * *

Note that when two editors are modifying preferences at the same * time, the last one to call apply wins. * *

Unlike {@link #commit}, which writes its preferences out * to persistent storage synchronously, {@link #apply} * commits its changes to the in-memory * {@link SharedPreferences} immediately but starts an * asynchronous commit to disk and you won't be notified of * any failures. If another editor on this * {@link SharedPreferences} does a regular {@link #commit} * while a {@link #apply} is still outstanding, the * {@link #commit} will block until all async commits are * completed as well as the commit itself. #不像commit方法,它同步的写preferences到持久化存储。apply提交变化值到内存中,Sharedpreference立即开启一个异步提交到磁盘中,而且你不会收到任何失败的信息。如果同时另一个editor调用commit方法,这是将会先执行apply方法,commit()将会被阻塞,知道所有的异步提交完成,以及提交自身。 * *

As {@link SharedPreferences} instances are singletons within * a process, it's safe to replace any instance of {@link #commit} with * {@link #apply} if you were already ignoring the return value. #在一个进程中,Sharedpreference是单例的,如果你已经不关注返回值了,使用apply替换commit就是安全的 * *

You don't need to worry about Android component * lifecycles and their interaction with apply() * writing to disk. The framework makes sure in-flight disk * writes from apply() complete before switching * states. #你不需要担心android组件风格和他们的相互作用,当使用apply写到磁盘存储的时候。框架确保在转变状态之前,运转的磁盘能够从apply()方法完成写操作。 * *

class='note'>The SharedPreferences.Editor interface * isn't expected to be implemented directly. However, if you * previously did implement it and are now getting errors * about missing apply(), you can simply call * {@link #commit} from apply(). #SharedPreferences.Editor接口是不希望直接实现的。然而,如果你之前已经实现了,并且现在正在获取有关缺少apply()方法的错误,则你只需要从apply()调用commit即可。 */ void apply(); } /** * Retrieve all values from the preferences. #从preference中取回所有键值对 *

Note that you must not modify the collection returned * by this method, or alter any of its contents. The consistency of your * stored data is not guaranteed if you do. #禁止改变返回的集合,或者修改内容。如果你做了,保存数据的一致性也不会被保证。 * * @return Returns a map containing a list of pairs key/value representing * the preferences. * * @throws NullPointerException */ Map getAll(); /** * Retrieve a String value from the preferences. #根据key获取对应的String类型的value值 * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * a String. * * @throws ClassCastException */ @Nullable String getString(String key, @Nullable String defValue); /** * Retrieve a set of String values from the preferences. #从preference中取回String类型值的集合 *

Note that you must not modify the set instance returned * by this call. The consistency of the stored data is not guaranteed * if you do, nor is your ability to modify the instance at all. * * @param key The name of the preference to retrieve. * @param defValues Values to return if this preference does not exist. * * @return Returns the preference values if they exist, or defValues. * Throws ClassCastException if there is a preference with this name * that is not a Set. * * @throws ClassCastException */ @Nullable Set getStringSet(String key, @Nullable Set defValues); /** * Retrieve an int value from the preferences. * * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * an int. * * @throws ClassCastException */ int getInt(String key, int defValue); /** * Retrieve a long value from the preferences. * * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * a long. * * @throws ClassCastException */ long getLong(String key, long defValue); /** * Retrieve a float value from the preferences. * * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * a float. * * @throws ClassCastException */ float getFloat(String key, float defValue); /** * Retrieve a boolean value from the preferences. * * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * a boolean. * * @throws ClassCastException */ boolean getBoolean(String key, boolean defValue); /** * Checks whether the preferences contains a preference. #判断是否包含key * @param key The name of the preference to check. * @return Returns true if the preference exists in the preferences, * otherwise false. */ boolean contains(String key); /** * Create a new Editor for these preferences, through which you can make * modifications to the data in the preferences and atomically commit those * changes back to the SharedPreferences object. * *

Note that you must call {@link Editor#commit} to have any * changes you perform in the Editor actually show up in the * SharedPreferences. * * @return Returns a new instance of the {@link Editor} interface, allowing * you to modify the values in this SharedPreferences object. */ Editor edit(); /** * Registers a callback to be invoked when a change happens to a preference. #注册一个回调函数,当preference被改变的时候,能够被调用 *

class="caution">Caution: The preference manager does * not currently store a strong reference to the listener. You must store a * strong reference to the listener, or it will be susceptible to garbage * collection. We recommend you keep a reference to the listener in the * instance data of an object that will exist as long as you need the * listener.

* * @param listener The callback that will run. * @see #unregisterOnSharedPreferenceChangeListener */ void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener); /** * Unregisters a previous callback. #取消注册之前的回调函数 * @param listener The callback that should be unregistered. * @see #registerOnSharedPreferenceChangeListener */ void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);}

Context.java中调用Sharedpreference方法的方法:

/*** 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的preferences内容,返回Sharedpreference,然后你可以取回和修改内容。Sharedpreference仅有一个实例能够被返回给任何调用者。意味着,一旦某个使用者作出改变,其他人都能看见他的编辑。* @param 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()).* @param mode Operating mode.** @return The single {@link SharedPreferences} instance that can be used*         to retrieve and modify the preference values.** @see #MODE_PRIVATE*/public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);/*** Retrieve and hold the contents of the preferences file, 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.** @param file 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()).* @param mode Operating mode.** @return The single {@link SharedPreferences} instance that can be used*         to retrieve and modify the preference values.** @see #getSharedPreferencesPath(String)* @see #MODE_PRIVATE* @removed*/public abstract SharedPreferences getSharedPreferences(File file, @PreferencesMode int mode);/*** Move an existing shared preferences file from the given source storage* context to this context. This is typically used to migrate data between* storage locations after an upgrade, such as moving to device protected* storage.** @param sourceContext The source context which contains the existing*            shared preferences to move.* @param name The name of the shared preferences file.* @return {@code true} if the move was successful or if the shared*         preferences didn't exist in the source context, otherwise*         {@code false}.* @see #createDeviceProtectedStorageContext()*/public abstract boolean moveSharedPreferencesFrom(Context sourceContext, String name);/*** Delete an existing shared preferences file.** @param name The name (unique in the application package) of the shared*            preferences file.* @return {@code true} if the shared preferences file was successfully*         deleted; else {@code false}.* @see #getSharedPreferences(String, int)*/public abstract boolean deleteSharedPreferences(String name);/*** Returns the absolute path on the filesystem where a file created with* {@link #getSharedPreferences(String, int)} is stored.* 

* The returned path may change over time if the calling app is moved to an* adopted storage device, so only relative paths should be persisted.** @param name The name of the shared preferences for which you would like* to get a path.* @return An absolute path to the given file.* @see #getSharedPreferences(String, int)* @removed*/public abstract File getSharedPreferencesPath(String name);

更多相关文章

  1. 查看Android(安卓)ADT Plugin版本的方法
  2. MediaPlayer介绍
  3. Android(安卓)Activity生命周期浅谈
  4. Android(安卓)- 电话拦截
  5. WebView的基本使用方法及 WebViewClient加载网页使用
  6. Android更新UI的两种方法——handler与runOnUiThread()
  7. Android(安卓)View 相关源码分析之二 继LayoutInflater来说
  8. Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部
  9. android中如何发送及接收数据(两种方法)?

随机推荐

  1. iOS还是Android?我应该选哪个平台来做应用
  2. VisionMobile:移动平台生态系统冲突报告(
  3. Android开发面试经——5.常见面试官提问A
  4. Android连接Tomcat服务器
  5. Android BSP成长计划随笔之虚拟设备搭建
  6. Android studio中正确引入so文件的方法
  7. android H5 应用内跳转Scheme协议
  8. Cocos2dx播放mp4文件(IOS和Android)
  9. Android(安卓)setTag方法的key问题解决办
  10. Android 程序猿的保活心酸史