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是另一个文件

frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java

    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
原创粉丝点击