SettingsProvider数据储存位置
来源:互联网 发布:笔记本安装mac系统 编辑:程序博客网 时间:2024/06/05 08:22
老早之前SettingProvider数据储存的位置在手机目录/data/data/com.android.providers.settings/databases下
不过目前的Android版本虽然也有这个目录,其中却没有对应的文件在,本文是看下当前的数据到底存储在哪里。
代码在在/home/lgy/code/mtk6797/frameworks/base/packages/SettingsProvider
插入流程分析
从插入代码为线索分析:
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
public Uri insert(Uri uri, ContentValues values) { ... switch (table) { ... case TABLE_SYSTEM: { if (insertSystemSetting(name, value, UserHandle.getCallingUserId())) { return Uri.withAppendedPath(Settings.System.CONTENT_URI, name); } } break; ... }只看system表的插入:
private boolean insertSystemSetting(String name, String value, int requestingUserId) { ... return mutateSystemSetting(name, value, requestingUserId, MUTATION_OPERATION_INSERT); }
private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) { ... case MUTATION_OPERATION_INSERT: { validateSystemSettingValue(name, value); return mSettingsRegistry .insertSettingLocked(SettingsRegistry.SETTINGS_TYPE_SYSTEM, owningUserId, name, value, getCallingPackage()); } ... }SettingsRegistry是内部类
public boolean insertSettingLocked(int type, int userId, String name, String value, ... final boolean success = settingsState.insertSettingLocked(name, value, packageName); ... }
SettingsState是另一个文件
public boolean insertSettingLocked(String name, String value, String packageName) { ... updateMemoryUsagePerPackageLocked(packageName, oldValue, value); scheduleWriteIfNeededLocked(); ... }
private void scheduleWriteIfNeededLocked() { if (!mDirty) { mDirty = true; writeStateAsyncLocked(); } }
private void writeStateAsyncLocked() { final long currentTimeMillis = SystemClock.uptimeMillis(); if (mWriteScheduled) { mHandler.removeMessages(MyHandler.MSG_PERSIST_SETTINGS); // If enough time passed, write without holding off anymore. final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis - mLastNotWrittenMutationTimeMillis; if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_SETTINGS_DELAY_MILLIS) { mHandler.obtainMessage(MyHandler.MSG_PERSIST_SETTINGS).sendToTarget(); return; } // Hold off a bit more as settings are frequently changing. final long maxDelayMillis = Math.max(mLastNotWrittenMutationTimeMillis + MAX_WRITE_SETTINGS_DELAY_MILLIS - currentTimeMillis, 0); final long writeDelayMillis = Math.min(WRITE_SETTINGS_DELAY_MILLIS, maxDelayMillis); Message message = mHandler.obtainMessage(MyHandler.MSG_PERSIST_SETTINGS); mHandler.sendMessageDelayed(message, writeDelayMillis); } ... }两条分支,不过最终都是发送了个消息,消息处理中会调用doWriteState
private void doWriteState() { ... AtomicFile destination = new AtomicFile(mStatePersistFile); ... FileOutputStream out = null; try { out = destination.startWrite(); XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(out, StandardCharsets.UTF_8.name()); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.startDocument(null, true); serializer.startTag(null, TAG_SETTINGS); serializer.attribute(null, ATTR_VERSION, String.valueOf(version)); final int settingCount = settings.size(); for (int i = 0; i < settingCount; i++) { Setting setting = settings.valueAt(i); writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(), setting.getValue(), setting.getPackageName()); if (DEBUG_PERSISTENCE) { Slog.i(LOG_TAG, "[PERSISTED]" + setting.getName() + "=" + setting.getValue()); } } serializer.endTag(null, TAG_SETTINGS); serializer.endDocument(); destination.finishWrite(out); ... }一看到xml就终于知道,是写到了一个xml文件中,并不是写到sqlite中。
文件地址确认
SettingsState中的成员
private final File mStatePersistFile;这个成员是xml的写入文件
在SettingsProvider中
private void ensureSettingsStateLocked(int key) { if (mSettingsStates.get(key) == null) { final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key)); SettingsState settingsState = new SettingsState(mLock, getSettingsFile(key), key, maxBytesPerPackage); mSettingsStates.put(key, settingsState); } }这个方法负责SettingsState的初始化
private File getSettingsFile(int key) { if (isGlobalSettingsKey(key)) { final int userId = getUserIdFromKey(key); return new File(Environment.getUserSystemDirectory(userId), SETTINGS_FILE_GLOBAL); } else if (isSystemSettingsKey(key)) { final int userId = getUserIdFromKey(key); return new File(Environment.getUserSystemDirectory(userId), SETTINGS_FILE_SYSTEM); } else if (isSecureSettingsKey(key)) { final int userId = getUserIdFromKey(key); return new File(Environment.getUserSystemDirectory(userId), SETTINGS_FILE_SECURE); } else { throw new IllegalArgumentException("Invalid settings key:" + key); } }从getSettingsFile中可以看到SettingsProvider三个表global,system和secure的文件,它们的路径是相同的,通过Environment.getUserSystemDirectory确立
frameworks/base/core/java/android/os/Environment.java
public static File getUserSystemDirectory(int userId) { return new File(new File(getSystemSecureDirectory(), "users"), Integer.toString(userId)); }
public static File getSystemSecureDirectory() { if (isEncryptedFilesystemEnabled()) { //加密文件系统分支,默认是关闭的 return new File(SECURE_DATA_DIRECTORY, "system"); } else { return new File(DATA_DIRECTORY, "system"); } }
private static final File DATA_DIRECTORY = getDirectory("ANDROID_DATA", "/data");依据ANDROID_DATA环境变量获取路径,获取不到的话就默认为/data。
获取到DATA_DIRECTORY后,后续还要添加"/ " + "system" + "/" + "users" + "/" + userId的值
例如我测试的手机上是/data/system/users/0,该目录的settings_global.xml,settings_secure.xml和settings_system.xml三个xml文件就是SettingsProvider中的数据文件。
0 0
- SettingsProvider数据储存位置
- Java中的数据储存位置
- android数据储存之应用安装位置
- Android N SettingsProvider的数据保存
- 储存数据
- 数据储存
- 数据储存
- 数据储存
- Java对象储存位置
- 【笨鸟先飞】android重新学习日记9--- 常量数据的储存位置
- 数据储存的发展
- erlang 数据储存
- 使用SQLite储存数据
- OC 数据储存
- Android数据储存
- IOS数据储存
- sharepreference储存数据
- OC数据储存
- 作业项目六
- c#媒体转发服务器HLS服务器实现1
- TLD目标跟踪算法学习(一)
- 大型网站架构系列:20本技术书籍推荐
- 从Java多态到策略模式
- SettingsProvider数据储存位置
- Ubuntu mysql 安装测试指南
- socket通信基础(一)
- FatMouse' Trade
- [AS2.2]Volley小记
- Win服务器SVN提交脚本
- ReactNative之ListView学习总结(一)简单demo
- python获取本地时间
- 【Struts】Struts2.0中struts.xml配置文件详解