android settings 源码,Android源码解析--Quick Search in Settings

欢迎大家加入群里交流:429664282

基于:android-6.0.1_r17 f4b8ad6

Android Settings中存在一个SearchIndexablesProvider,它提供了可供快速检索的设置项。通过它,我们可以决定哪些系统设置可以被快速检索,那些可以不被检索。

SearchIndexablesProvider简介

SearchIndexablesProvider是Android标准API,在SDK中可以找到,路径是"android.provider.SearchIndexablesProvider"。它是一个虚基类,提供了一些抽象方法和常用方法。

抽象方法如下:

Cursor queryXmlResources(String[])

Cursor queryRawData(String[])

Cursor queryNonIndexableKeys(String[])

queryXmlResources方法返回一个Cursor,这个Cursor中包含了所有可以被索引的XmlResource,方法的参数是个String数组,用来表示传入查询的列。

queryRawData方法同queryRawData很类似,唯一区别是返回所有可以被索引的RawData。

queryNonIndexableKeys返回所有可以不被所有的NonIndexableKey。

检索数据来源:SearchIndexableResources

在Settings中,所有可供检索的数据资源,均被定义在SearchIndexableResources类中。

例如,Wifi设置页面的所有可供检索的数据,都通过WifiSettings.java提供。

static {

sResMap.put(WifiSettings.class.getName(),

new SearchIndexableResource(

Ranking.getRankForClassName(WifiSettings.class.getName()),

NO_DATA_RES_ID,

WifiSettings.class.getName(),

R.drawable.ic_settings_wireless));

特殊检索数据:Indexable

在Settings中,提供了一类特殊的检索数据,那就是实现了Indexable接口的类。

Indexable是定义在Settings内部的一种检索资源,通过代码的方式,返回可供检索的数据,包括SearchIndexableResource和SearchIndexRaw。

所有实现了Indexable的类,必须提供一个public static的SEARCH_INDEX_DATA_PROVIDER变量,用来供Settings利用反射获取到相应的检索数据。

771f53625528fcbcc8a5810b8c4c9795.png

检索数据提供者:SettingsSearchIndexablesProvider

在Settings中,SettingsSearchIndexablesProvider实现了SearchIndexablesProvider,并且提供了可供检索的数据资源。这个数据资源以静态map的方式定义在SearchIndexableResources中,并且在queryXmlResources方法中返回给数据请求者。

101ab7f18b9d3a046896d22b0d426126.png

Settings并未提供任何的RawData和NonIndexableKey,所以它的queryRawData返回了一个空的Cursor。

8bb54fc41759dfba04a025886e22ccfb.png

更新检索数据库

在每次打开Settings导航页面的时候,Index.update()方法都会被调用,用来更新检索数据。

47e43afdbf68457e424cbdceb32e2fca.png

Step1. 获取所有SearchIndexablesProvider.

96f43de6d67ca6c20e021f8c83506968.png

Step2. 添加可供检索的数据到缓存:addIndexablesFromRemoteProvider

对于每一个SearchIndexablesProvider,都需要进行这个操作。

Step2.1. 从XmlResource中添加检索数据:addIndexablesForXmlResourceUri

所有定义在SearchIndexableResources中的检索数据,均会在这一步中被添加进来。接下来,让我们看看具体实现:

Step2.1.1 获取检索数据的Cursor

3572f421726c9caee75b221aafae4752.png

Step2.1.2 创建SearchIndexableResource,并加入到更新数据的缓存列表:

0696ecc54b84ae63aba1ebdd0b37f309.png

262c5175e8be190c73ae14982e77c772.png

Step2.2. 从RawData中添加检索数据:addIndexablesForRawDataUri

Settings并未提供任何RawData,所以我们可以忽略这个步骤。

Step3. 添加不可供检索的数据到缓存

Settings并未提供任何NonIndexableKey,所以我们可以忽略这个步骤。

Step4. 更新缓存的检索数据

更新缓存的检索数据在updateInternal()方法中实现,下面我们来逐步分析下。

缓存数据结构

a65b19e3005906e0ad8910e4f831a31f.png

到现在为止,Settings提供的检索数据均被添加到"dataToUpdate"列表中。其他两个未包含任何Settings提供的检索数据。

Step4.1 创建一个UpdateIndexTask的后台任务来更新检索数据库

ff96a89c1f43dc4869917926b8b0ce21.png

我们下面只关心dataToUpdate的相关操作。

Step4.2 更新dataToUpdate缓存:processDataToUpdate

在这个方法中,我们对每一个SearchIndexableData都使用indexOneSearchIndexableData方进行更新。

b34115048d4eaf5aa0446ec7a8a8112d.png

Step4.3 对检索数据进行索引:indexOneSearchIndexableData

这里的检索数据可以包括RawData和XmlResource,又或者Settings返回的SearchIndexableResource。

这里为什么是SearchIndexableResource?因为SettingsSearchIndexablesProvider把所有可以检索的数据都已SearchIndexableResource插入到Cursor中,并且返回给数据查询者,这里也就是Settings本身。

6499f95a99436303029bbca478959fe9.png

Step4.4 对每一条检索数据资源进行数据检索:indexOneResource

前面我们提到过,Settings里面有一种特殊的检索数据资源:Indexable。

在这里,如果我们发现这条检索数据资源的xmlResId是NO_DATA_RES_ID,也就是说,当前这个检索数据资源是一条特殊的检索数据资源。我们就需要利用反射机制得到它的pusblic static的SEARCH_INDEX_DATA_PROVIDER。

Step4.4.1. 处理普通的检索数据资源:xmlResId != NO_DATA_RES_ID

3ac6fcb329be7ec7aa20b0ef9007a423.png

Step4.4.1.1. 从XML中解析检索数据:indexFromResource

在这里就到了整个实现流程的最末端了,解析整个PreferenceScreen的XMl文件,并且把每一个符合条件的项加入到检索数据库。

Step4.4.2. 处理特殊的检索数据资源:Indexable

b9fa8442d5dc6b5592adaf0970159205.png

Step4.4.2.1. 从特殊的检索数据源获取检索数据:indexFromProvider

当拿到SEARCH_INDEX_DATA_PROVIDER变量后,我们得到它的两个方法返回值,根据返回值的具体内容,我们将其更新到数据库。

android源码解析(十七)-->Activity布局加载流程

版权声明:本文为博主原创文章,未经博主允许不得转载. 好吧,终于要开始讲讲Activity的布局加载流程了,大家都知道在Android体系中Activity扮演了一个界面展示的角色,这也是它与andr ...

Android源码解析系列

转载请标明出处:一片枫叶的专栏 知乎上看了一篇非常不错的博文:有没有必要阅读Android源码 看完之后痛定思过,平时所学往往是知其然然不知其所以然,所以为了更好的深入Android体系,决定学习an ...

Android源码解析——LruCache

我认为在写涉及到数据结构或算法的实现类的源码解析博客时,不应该急于讲它的使用或马上展开对源码的解析,而是要先交待一下这个数据结构或算法的资料,了解它的设计,再从它的设计出发去讲如何实现,最后从实现的角 ...

Android源码解析——Toast

简介 Toast是一种向用户快速展示少量信息的视图.当它显示时,它会浮在整个应用层的上面,并且不会获取到焦点.它的设计思想是能够向用户展示些信息,但又能尽量不显得唐突.本篇我们来研读一下Toast的源 ...

Android源码解析——AsyncTask

简介 AsyncTask 在Android API 3引入,是为了使UI线程能被正确和容易地使用.它允许你在后台进行一些操作,并且把结果带到UI线程中,而不用自己去操纵Thread或Handler.它 ...

Android 源码解析 之 setContentView

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41894125,本文出自:[张鸿洋的博客] 大家在平时的开发中,对于setCont ...

Android 源码解析之AsyncTask

AsyncTask相信大家都不陌生,它是为了简化异步请求.更新UI操作而诞生的.使用它不仅可以完成我们的网络耗时操作,而且还可以在完成耗时操作后直接的更新我们所需要的UI组件.这使得它在android ...

【Android源码解析】View.post()到底干了啥

emmm,大伙都知道,子线程是不能进行 UI 操作的,或者很多场景下,一些操作需要延迟执行,这些都可以通过 Handler 来解决.但说实话,实在是太懒了,总感觉写 Handler 太麻烦了,一不小心 ...

Android 源码解析:单例模式-通过容器实现单例模式-懒加载方式

本文分析了 Android 系统服务通过容器实现单例,确保系统服务的全局唯一. 开发过 Android 的用户肯定都用过这句代码,主要作用是把布局文件 XML 加载到系统中,转换为 Android 的 ...

随机推荐

Linux下的C Socket编程 -- server端的继续研究

Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...

Windows平台下和跨平台的相关公共库

以下主要包含windows下公共库以及跨平台公共库: 1. google base库:google下chromium项目的跨平台公共库: 2. vc_common_src:即HP_SOCKET项目中的 ...

CSU 1116 Kingdoms

题意:给你n个城市,m条被摧毁的道路,每条道路修复需要c元,总共有k元,给你每个城市的人口,问在总费用不超过k的情况下 与1号城市相连的城市的最大总人口(包括1号城市) 思路:1号城市是必取的,剩余最 ...

JAVA运行java程序

程序代码: public class f{ public static void main(String[] args){ String foo1 = args[1]; String foo2 = a ...

[转]Asp.net三种事务处理

事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

Codeforces 616E - Sum of Remainders

616E Sum of Remainders Calculate the value of the sum: n mod 1 + n mod 2 + n mod 3 + - + n mod m. As ...

C# 程序性能提升篇-2、类型(字段类型、class和struct)的错误定义所影响性能浅析

前景提要: 编写程序时,也许你不经意间,就不知不觉的定义了错误的类型,从而发生了额外的性能消耗,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候 ...

用TextKit实现图文混排(转载)

Textkit是iOS7新推出的类库,其实是在之前推出的CoreText上的封装,有了这个TextKit,以后不用再拿着CoreText来做累活 了,根据苹果的说法,他们开发了两年多才完成,而且他们在 ...

Rabbitmq 性能测试

背景: 线上环境,出了一起事故,初步定位是rabbitmq server. 通过抓包发现,是有多个应用使用同一台rabbitmq server.并且多个应用使用rabbitmq的方式也不一样.发现有以 ...

使用DbUtils对JDBC封装实现面向实体查询

直接上代码 package org.smart4j.chapter2.helper; import org.apache.commons.dbcp2.BasicDataSource; import o ...

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值