by 潮流网络@jfdeng
1
Settings 搜索说明文档
简介
Settings 搜索是单独的一个模块,此文档主要讲解 9.0 上的原生搜索的功能,其源码位于
android/packages/apps/SettingsIntelligence 下,SettingsIntelligence 是一个单独的应用
下面简单描述下搜索的主要业务流程:
1.Settings 中点击搜索框,跳转至 SettingsIntelligence 中的搜索页面,即 SearchActivity
而 SearchActivity 又切换到了 SearchFragment.
2.SearchFragment 中,SearchFeatureProviderImpl 配合 loaderManager,获取到数据库中的数据,
然后返回给 Adapter,并绑定到 RecycleView 中显示
3.在 onBindViewHolder 时通过 onBind 实现对应点击事件的跳转
数据获取
很疑惑,SettingsIntelligence 中数据库的数据是怎么来的呢,是如何获取到的 Settings 中的相关
页面的数据的呢?流程如下:
1.SearchFragment 创建时进行了一些对象创建,如,也包括数据的初始化,如
mSavedQueryController,SearchFeatureProviderImpl 等等,mSearchFeatureProvider 调用
updateIndexAsync 开启数据库的初始化
by 潮流网络@jfdeng
2
2.监听 searchview 输入框,通过 restartLoaders 调用 loaderManager 开启加载数据流程
3.load 创建成功回调至 onCreateLoader
4.mSearchFeatureProvider 调用 getSearchResultLoader 方法,得到 SearchResultLoader 对
象,SearchResultLoader 在子线程中进行数据查找 loadInBackground
by 潮流网络@jfdeng
3
5.loadInBackground 时通过 SearchResultAggregator 的 fetchResults 进行数据查找以及过滤.并
且创建了一个 task 集合,然后遍历的形式开启了 task 让其执行.之后将执行的结果返回到了
taskResult 结果集中
6.我们看看 SearchFeatureProviderImpl 中构建各类获取数据的 task,包括
DatabaseResultTask,InstalledAppResultTask,AccessibilityServiceResultTask 等等.
by 潮流网络@jfdeng
4
且每个 task 都是继承自 SearchQueryTask,而 SearchQueryTask 又是继承自 FutureTask,因为
FutureTask 可以在线程运行结束后将结果返回.SearchQueryTask 内封装了 call 方法的回调,调
用抽象方法 query 完成数据的返回.
7.子类例如 DatabaseResultTask,只需要实现方法 query 即可返回数据
by 潮流网络@jfdeng
5
8.可以看到,query 中通过一系列查找的方法将数据添加到了 resultSet 结果集中,我们选取
其中第一个 firstWordQuery 方法查看其实现,最终也是通过 query 方法调用
9.query 中则拿到了 Sqlite 数据库的操作对 IndexDatabaseHelper 进行数据库操作,这个是
一个单例对象,且内部定义了一些表和初始化的代码.
by 潮流网络@jfdeng
6
整体数据的获取流程结束了,但是问题还是没解决啊,数据库的数据是哪里来的.其实就在前
面几步中,我们现在回头看第 1 步 SearchFragment 的 onCreate 方法中就包括
mSearchFeatureProvider.updateIndexAsync,我们看看其内部实现
原来在这里,开启了一个异步任务进行了 indexing 的操作
其中实现如下,最重要的就是 queryIntentContentProviders 这个方法,通过包管理器拿到
了 ContentProvider,然后再通过 ContentProvider 查询对应进程内的数据,更新到了
SettingsIntelligence 的数据库中
by 潮流网络@jfdeng
7
其中PROVIDER_INTERFACE定义如下
我们可以搜索下 Settings 中是否有包含这个 action,果然有声明一个内容提供者.
下面看看 Settings 中内容提供者是怎么提供的数据吧
数据提供
1.我们看看 SettingsSearchIndexablesProvider 的代码,发现只有几个 query*相关的
方法,而且是重写的,例如下图
by 潮流网络@jfdeng
8
那么肯定是父类做了一些操作,我们看看父类做了什么
2.SearchIndexablesProvider 中做了一些封装和修改.对 query 方法进行了分类查询