Android中常见的几种存储方式:
- SharedPreferences
- SQLite数据库存储
- 文件存储
- 网络存储
其中也许最常用的就是SharedPreferences存储和文件存储了,今天总结一下SharedPreferences。带着问题学习SharedPreferences:
问题:
- 存储的位置是在哪
- SharedPreferences存储的文件格式是什么
- 如何查看
- 创建的时候需要context,不同的context创建有没有区别
- 创建的几种mode以及区别
- apply和commit的区别
- 存取数据使用多张表还是一张表
看完下面的讲解,你应该就能回答上面的问题了
google官方说明
SharedPreferences 类提供了一个通用框架,以便您能够保存和检索原始数据类型的永久性键值对。 您可以使用 SharedPreferences 来保存任何原始数据:布尔值、浮点值、整型值、长整型和字符串。 此数据将跨多个用户会话永久保留(即使您的应用已终止亦如此)。
要获取应用的 SharedPreferences 对象,请使用以下两个方法之一:
- getSharedPreferences() - 如果您需要多个按名称(使用第一个参数指定)识别的首选项文件,请使用此方法。
- getPreferences() - 如果您只需要一个用于 Activity 的首选项文件,请使用此方法。 由于这将是用于 Activity 的唯一首选项文件,因此无需提供名称。
我先在Activity A中写入
SharedPreferences settings = getSharedPreferences("test", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("num", 23);
System.out.println("-----------写入");
打印:
I/System.out: ———–写入
然后在Activity B中查看
SharedPreferences settings = getSharedPreferences("test", 0);
int num = settings.getInt("num", 0);
System.out.println("-----------num="+num);
打印:
I/System.out: ———–num=23
存储的位置是在哪
如果你使用的是3.0以前的Android studio版本,可以在通过DDMS的【File Explorer】中查看,如果你使用的是3.0以及以后的Android studio版本,可以直接通过一下步骤打开
点击 View > Tool Windows > Device File Explorer 或工具窗口栏中的 Device File Explorer 按钮以打开设备文件浏览器。
注意需要用模拟器查看,手机没有root是看不到的
找到data\data\程序包名\shared_prefs目录,你会发现你刚创建的文件
SharedPreferences存储的文件格式是什么
我想你应该也看到了是xml文件
内容是:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<int name="num" value="23" />
</map>
如何查看
如果是开发上面就是查看过程,如果是真机需要把手机root,才有权限查看
创建的时候需要context,不同的context创建有没有区别
我是在不同的Activity中写入和查看的,但是操作的是同一个test.xml,所以不同的Context操作只要getSharedPreferences(“test”, 0);获取SharedPreferences时传入的第一个参数name相同就得到是相同的SharedPreferences,操作的是同一个xml文件。
那么如何获取一个Activity单独的SharedPreferences呢?Google已经说了
getPreferences() - 如果您只需要一个用于 Activity 的首选项文件,请使用此方法。 由于这将是用于 Activity 的唯一首选项文件,因此无需提供名称
可以查看源码,其实就是获取了当前Activity的ClassName,所以这个name是单独的,所以产生的也是用于 此Activity 的唯一首选项文件
/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
* {@link #getSharedPreferences(String, int)} method by passing in this activity's
* class name as the preferences name.
*
* @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default
* operation.
*
* @return Returns the single SharedPreferences instance that can be used
* to retrieve and modify the preference values.
*/
public SharedPreferences getPreferences(@Context.PreferencesMode int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
创建时的几种mode以及区别
上面获取SharedPreferences的时候我直接使用的是getSharedPreferences(“test”, 0),第二个参数传入的是0,代表操作模式是MODE_PRIVATE
操作模式有以下几种:
- MODE_PRIVATE
- MODE_WORLD_READABLE
- MODE_WORLD_WRITEABLE
- MODE_APPEND
- MODE_MULTI_PROCESS
Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容, 而不是擦除以前的,否则就创建新文件。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取。
MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
以上是我看的网上的说法,但是我在最新的Android Studio上开发,也就是在Android Studio3.1上去看到了下面的场景:
MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE和MODE_MULTI_PROCESS都被废弃了
然后我又试了下MODE_APPEND,又给了我以下的提示:
Must be one or more of: Context.MODE_PRIVATE, Context.MODE_WORLD_READABLE, Context.MODE_WORLD_WRITEABLE, Context.MODE_MULTI_PROCESS less… (⌘F1)
看来目前能用的只能是MODE_PRIVATE了,其他的不用考虑了
apply和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.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call commit wins.
*
* <p>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.
*
* @return Returns true if the new values were successfully written
* to persistent storage.
*/
boolean commit();
1,commit方法是有一个boolean的返回值
2,当数据变化进行存储时是一个原子性的操作
3,当两个editor对象同时对一个共享的preferences参数进行操作时,永远都是最后一个调用commit方法的editor变更了最后的数据值
/**
* 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.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call apply wins.
*
* <p>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.
*
* <p>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.
*
* <p>You don't need to worry about Android component
* lifecycles and their interaction with <code>apply()</code>
* writing to disk. The framework makes sure in-flight disk
* writes from <code>apply()</code> complete before switching
* states.
*
* <p 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 <code>apply()</code>, you can simply call
* {@link #commit} from <code>apply()</code>.
*/
void apply();
1,apply方法是没有返回值的
2,当两个editor同时对preferences对象编辑时,也是最后一个调用apply方法的对象编辑数据
3,apply的提交操作也是原子性的
以上是我直接参考了这篇博客的结论:https://www.jianshu.com/p/c8d10357c939
其实我们Android studio的很强大,当你使用editor.commit();的时候直接推荐你使用apply,commit直接写入持久化内存,apply在后台处理它
Consider using apply() instead; commit writes its data to persistent storage immediately, whereas apply will handle it in the background
他们的区别总结:
apply()没有返回值,commit()有返回值,在不关心结果的时候推荐使用apply()
commit()直接写入持久化内存,是同步过程,速度比apply()慢,apply()是异步的提交,速度更快
存取数据使用多张表还是一张表
我们知道SharedPreferences存储的格式是xml,既然是xml就要用到解析,只不过这个解析过程我们是看不到的也不需要去关心,但是解析的速度却会影响到我们的用户体验,加入一张表里面有很多数据,比如你把一个页面的数据存起来了,数据量比较大,那么这个时候推荐为这些数据单独建立一个表,也就是推荐不同的数据放不同的表里面,防止所有数据都放在一张表里面一次读取要耗费很长时间