简介:
前阵子遇到个问题,OTA升级之后设置中的默认设置项发生了改变,后来查找发现设置中该设置项是通过读取系统数据库中的数据来决定选项是否开启,所以顺带查看了一下SettingsProvider源码,后来发现问题跟SettingsProvider没关系,但还是抽时间将阅读内容整理记录下来。
模块总览:
该模块主要用于记录一些重要的系统数据,模块代码位于:
\frameworks\base\packages\SettingsProvider
代码不多,就几个java文件,围绕一个SettingsProvider展开,类关系图如下:
所以manifest文件也十分简洁:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.providers.settings"
coreApp="true"
android:sharedUserId="android.uid.system">
<application android:allowClearUserData="false"
android:label="@string/app_label"
android:process="system"
android:backupAgent="SettingsBackupAgent"
android:killAfterRestore="false"
android:icon="@mipmap/ic_launcher_settings"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
<provider android:name="SettingsProvider"
android:authorities="settings"
android:multiprocess="false"
android:exported="true"
android:singleUser="true"
android:initOrder="100" />
</application>
</manifest>
在framework中封装了一个Settings类,提供对SettingsProvider的读写接口。代码路径位于:
frameworks\base\core\java\android\provider\Settings.java
这里主要从以下两点来分析:
- 应用的初始化
- 数据的读写
1.应用的初始化
SettingsProvider的主要功能大多都在子类SettingsRegistry中实现,以前数据都记录在数据库中,6.0之后就不再使用数据库作为主要存储了,数据主要存储在xml文件中,这些文件路径定义在SettingsRegistry中:
private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml";
private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
文件路径定义为:
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);
}
}
所以就是如下三个文件:
data/system/users/0/settings_global.xml
data/system/users/userid/settings_system.xml
data/system/users/userid/settings_secure.xml
首先来分析SettingsProvider的onCreate方法:
@Override
public boolean onCreate() {
synchronized (mLock) {
mUserManager = UserManager.get(getContext());
mPackageManager = AppGlobals.getPackageManager();
mHandlerThread = new HandlerThread(LOG_TAG,
Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
//初始化SettingsRegistry,会在这里做一次数据迁移
mSettingsRegistry = new SettingsRegistry();
}
//注册广播监听
registerBroadcastReceivers();
//这里会监听用户限制相关的一些改变,比如分享位置,安装位置来源应用,使能adb等,然后对相关xml文件做修改
startWatchingUserRestrictionChanges();
return true;
}
SettingsRegistry的初始化如下:
public SettingsRegistry() {
mHandler = new MyHandler(getContext().getMainLooper());