Android平台用于存储轻量级数据的存储方式,以键值对(key-value)的方式来进行存储,本质上是一个xml 文件。
1、通过Context,获取SharedPreferences对象;
2、创建SharedPreferences.Editor对象;
3、写入数据并执行commit操作;
Context context;
SharedPreferences sharedPreferences = context.getSharedPreferences("sptest",MODE_PRIVATE);
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("name","名字");
editor.commit();
执行上面的操作之后,就会在 data/data/你的应用名称/shared_prefs 文件夹下创建 sptest.xml 文件,并写入对应的数据。
在getSharedPreferences
传入的参数,为 MODE_PRIVATE,也就是默认的模式。Android支持的模式一共有以下四种操作模式。四种操作模式分别为:
1. MODE_APPEND: 追加方式存储
2. MODE_PRIVATE: 私有方式存储,其他应用无法访问
3. MODE_WORLD_READABLE: 表示当前文件可以被其他应用读取
4. MODE_WORLD_WRITEABLE: 表示当前文件可以被其他应用写入
现在只推荐使用MODE_PRIVATE这种模式,其他的几种模式,已经被官方弃用了,不再推荐使用。甚至在N版本以上,会直接抛异常。
1、通过上面获取到的SharedPreferences,执行器getString 方法即可;
String name = sharedPreferences.getString("name", "默认值");
SharedPreferences
是一个接口,对应的实现者是,SharedPreferencesImpl
。在我们创建SharedPreferences的时候,需要传入对应的文件名称,然后将对应文件的数据读取到内存中,这个操作是异步的,在其内部新创建了一条名称为SharedPreferencesImpl-load
的Thread进行读取的操作,
private void startLoadFromDisk() {
synchronized (this) {
mLoaded = false;
}
new Thread("SharedPreferencesImpl-load") {
public void run() {
synchronized (SharedPreferencesImpl.this) {
loadFromDiskLocked();
}
}
}.start();
}
当我们进行数据新增的时候,并不会立即进行数据落地,会将所有的操作,都先放进内存里面的Map,
private final Map mModified = Maps.newHashMap();
public Editor putString(String key, String value) {
synchronized (this) {
mModified.put(key, value);
return this;
}
}
当需要进行数据落地的时候,需要调用commit
或者apply
方法。
public void apply() {
...
final Runnable awaitCommit = new Runnable() {
public void run() {
try {
mcr.writtenToDiskLatch.await();
} catch (InterruptedException ignored) {
}
}
};
Runnable postWriteRunnable = new Runnable() {
public void run() {
awaitCommit.run();
QueuedWork.remove(awaitCommit);
}
};
SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);
}
private void writeToFile(MemoryCommitResult mcr) {
if (mFile.exists()) {
if (!mcr.changesMade) {
mcr.setDiskWriteResult(true);
return;
}
if (!mBackupFile.exists()) {
if (!mFile.renameTo(mBackupFile)) {
Log.e(TAG, "Couldn't rename file " + mFile
+ " to backup file " + mBackupFile);
mcr.setDiskWriteResult(false);
return;
}
} else {
mFile.delete();
}
}
try {
FileOutputStream str = createFileOutputStream(mFile);
if (str == null) {
mcr.setDiskWriteResult(false);
return;
}
XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str);
FileUtils.sync(str);
str.close();
ContextImpl.setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
try {
final StructStat stat = Libcore.os.stat(mFile.getPath());
synchronized (this) {
mStatTimestamp = stat.st_mtime;
mStatSize = stat.st_size;
}
} catch (ErrnoException e) {}
mBackupFile.delete();
mcr.setDiskWriteResult(true);
return;
} catch (XmlPullParserException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
} catch (IOException e) {
Log.w(TAG, "writeToFile: Got exception:", e);
}
if (mFile.exists()) {
if (!mFile.delete()) {
Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
}
}
mcr.setDiskWriteResult(false);
}
这两者的差别是,commit 是同步操作,而apply 是异步实现的。在将writeToFile
方法中,首先将当前文件重命名为备份文件,然后从当前文件中获取文件输出流,并将MemoryCommitResult
中保存的备份数据,写入到文件输出流中。如果写入成功,则删除备份文件,返回true。如果写入失败,则删除当前文件,在下一次从备份文件中恢复过来。
两种都不支持,如果非要使用,会存在数据丢失的情况。
支持,但要访问的应用的Preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限,否则都是访问不了的。
可以,但要求你的手机是root的机子,按照应用创建的方式,赋予对应的用户和用户组,还有响应的权限即可。如果遇到不成功的情况,可能是权限没有给到位,可以参考:http://bbs.elecfans.com/jishu_1654998_1_1.html