Android O Settings源码流程分析(搜索栏篇(中))

Android O Settings 

Settings 搜索栏

中篇——实现原理

初始化候选项:

相关类:

/packages/apps/Settings/src/com/android/settings/SettingsActivity.java

/packages/apps/Settings/src/com/android/settings/search/SearchActivity.java

/packages/apps/Settings/src/com/android/settings/search/SearchFragment.java

/packages/apps/Settings/src/com/android/settings/search/SearchFeatureProviderImpl.java

/packages/apps/Settings/src/com/android/settings/search/DatabaseIndexingManager.java

/packages/apps/Settings/src/com/android/settings/search/IndexDatabaseHelper.java

/packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java

/frameworks/base/core/java/android/provider/SearchIndexableResource.java

/packages/apps/Settings/src/com/android/settings/search/SettingsSearchIndexablesProvider.java

/frameworks/base/core/java/android/provider/SearchIndexablesProvider.java

首先来分析系统设置可以对哪些设置项进行构建搜索数据库,并且是如何加载的;

SearchFragment.java——>onCreate():

            ……

SearchFeatureProviderImpl.java——>updateIndexAsync():

getIndexingManager():

DatabaseIndexingManager.java——>indexDatabase():

可以看到在方法中开启了一个线程任务IndexingTask

它在后台所执行的方法 performIndexing():

首先 查找系统中所有的配置了"android.content.action.SEARCH_INDEXABLES_PROVIDER"的Provider

添加其他APP的设置项 :addIndexablesFromRemoteProvider();

添加其他APP中不需要被搜索到的设置项 :addNonIndexablesFromRemoteProvider();

上面的addIndexablesFromRemoteProvider会添加设置项到内存中的一个mDataToProcess对象里,然后updateDate()将该对象更新到数据库中

来看addIndexablesFromRemoteProvider()方法:

  • 根据当前包名创建对应包的context对象。
  • 根据当前包名构建指定URI,例如,
  • settings:content://com.android.settings/settings/indexables_xml_res
  • 然后通过context对象查找对应的Provider的数据
  • 所有的要被列入搜索项的所在的APP的Provider都要继承SearchIndexablesProvider
  • SearchIndexablesProvider继承ContentProvider;

         ……

在该类中定义了查询路径并且实现通过匹配不同Uri进行查找;

而在Settings中,则是由SettingsSearchIndexablesProvider实现相应查询逻辑

在该类中采用Matrix构建虚拟的数据表,并通过SearchIndexableResource.values获取到所有添加到map集合中的SearchIndexableResource;

回到addIndexablesFromRemoteProvider();

看一下方法addIndexablesForXmlResourceUri():

首先获取到指定包对应的ContentResolver,然后解析Cursor数据并且添加到UpdateData对象的dataToUpdate属性中,该属性是一个List集合;

回到performIndexing()继续分析

然后执行方法updateDatabase():

接着看方法addDataToDatabase():(加载数据到搜索数据库中

看它里面的重要方法indexOneSearchIndexableData():

两种添加到数据库中的方法;

接着看方法indexOneResource():

                    ……

                   ……

                                    ……

indexFromResource() --> 使用XmlResourceParser解析xml布局

                               ……

                        ……

indexFromProvider() --> 获取需要解析的布局,再次调用indexFromResource()方法;

             ……

updateOneRowWithFilteredData() --> updateOneRow() --> 此方法最终将解析的数据更新至数据库

在此过程中涉及到了一个组装数据的类SearchIndexableResources.java

例如将WiFi相关设置项加入到搜索数据匹配库:

添加有两种方式:

一种是直接在new SearchIndexableResource() 时传入布局文件

另一种为"NO_DATA_RES_ID"表示此搜索项匹配没有需要解析的xml文件,此xml的解析在DatabaseIndexingManager.java中,

采用第二种时,需要在对应的类中创建一个SEARCH_INDEX_DATA_PROVIDER,类型为SearchIndexProvider,继承BaseSearchIndexProvider并复写其两个方法: getXmlResourcesToIndex() 和 getNonIndexableKeys().

这些“WiFi”候选项被存入一个HashMap中 :

以候选项类名作为key,把每个候选项封装成SearchIndexableResource对象作为value;

而SearchIndexableResource是继承于SearchIndexableData:

而它是出现在addDataToDatabase()中循环遍历的对象,然后添加至数据库中;

再次回到方法 performIndexing(),很显然一个和数据库相关的类:IndexDatabaseHelper.java:

       ……

通过名字可以看出数据库search_index.db是与搜索索引相关的数据库

数据库路径:/data/user_de/0/com.android.settings/databases/search_index.db

search_index.db 数据库的prefs_index表格中存放的就是搜索的设置选项

注:该数据库的初始化不是在开机时,而是在每一次打开Settings或者切换用户时进行。(系统为每一个用户维护一个单独的search_index)

至此,Settings搜索框初始化搜索索引完成;

点击进入下篇——搜索及页面跳转

猜你喜欢

转载自blog.csdn.net/qq_34149526/article/details/83378184