默认设置
「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
SettingsProvider存储数据
-
SettingsProvider会创建一个数据库,用户在修改系统设置的时候,大部分都是在修改SettngsProvider中的值,当SettingsProvider中的数据发生修改的时候,系统服务会监听到这个修改,然后通过修改一些底层设置,从而修改系统设置和属性。
-
在Android 6.0版本时,SettingsProvider被重构,Android从性能、安全等方面考虑,把SettingsProvider中原本保存在settings.db中的数据,目前全部保存在XML文件中。
-
在SetttngsProvider的启动过程中,会创建数据库,把默认设置的数据值写入数据库,然后将数据库中的数据全部迁移到xml文件中。
SetttngsProvider启动流程
frameworks\base\packages\settingsprovider\src\com\android\providers\settings\SettingsProvider.java
-
调用 onCreate() 方法
1.1. 实例化了HandlerThread的对象mHandlerThread,优先级是THREAD_PRIORITY_BACKGROUND
1.2. 实例化SettingsRegistry的实例mSettingsRegistry。
1.3. 接下来注册了一个广播接收器,关心的广播包括设备用户变化和app卸载等的广播。
-
调用 migrateAllLegacySettingsIfNeeded 方法。调用了makeKey方法来获得key,分别是Global、System、Secure三种类型,获得之后通过getSettingsFile方法创建三种类型的xml文件,存放数据。
Global:所有的偏好设置对系统的所有用户公开,第三方APP有读没有写的权限; System:包含各种各样的用户偏好系统设置; Secure:安全性的用户偏好系统设置,第三方APP有读没有写的权限。
-
实例化了一个DatabaseHelper,它是SQLiteOpenHelper的子类,然后调用它的getWritableDatabase方法,获得指向数据库文件的SQLiteDatabase的实例database
-
在实例化 时,会调用它的onCreate方法,分别创建system,Secure,Global三个数据库表,调用loadSettings方法,加载许多默认值写入数据库中,这些默认值大部分定义在defaults.xml文件(/frameworks/base/packages/SettingsProvider/res/values/defaults.xml)中
-
调用migrateLegacySettingsForUserLocked方法
1.1. 调用ensureSettingsStateLocked方法,实例化了settingsState对象指向了sysytem的数据文件(/data/system/users/0/settings_system.xml)。
1.2 调用migrateLegacySettingsLocked方法,查询数据库,先查询出所有System的信息,然后在循环中作为SettingsState.insertSettingLocked()的参数。
1.3 insertSettingLocked()方法,将每个设置项封装到Setting对象中,再将setting对象方法放进ArrayMap<String, Setting> 对象 mSettings中。
1.4 执行SettingsState的persistSyncLocked方法,它的功能就是将settingsState拥有的设置项从内存中固化到xml文件中。
-
把数据库文件删除。
SettingsProvider封装
-
为保证在整个Android的Java层任意一个地方里面能够方便,快捷的使用SettingsProvider进行数据查询,数据插入,数据更新,所以在framework的provider里面有一个类Settings.java对使用SettingsProvider进行了封装。
-
在settings.java代码创建了三个静态内部类,System,Secure,Global分别对应SettingsProvider中的System,Secure,Global三种数据类型,
-
Global、Secure、System三个静态内部类会分别持有自己NameValueCache的实例变量,每个NameValueCache持有指向SettingsProvider中的SettingsProvider.java的AIDL远程调用IContentProvider,因此,查询数据需要经过NameValueCache的getStringForUser()方法,插入数据需要经过putStringForUser()方法。最终会调到Settingsprovider.java,对数据存取。