从上面已经知道搜索框布局的具体加载是在SearchFragment中进行的,下面就来看看SearchFragment的onCreate方法: \packages\apps\settings\src\com\android\settings\search\SearchFragment.java 在onCreate方法中调用了SearchFeatureProvider的updateIndexAsync方法,它的具体实现是在SearchFeatureProviderImpl中实现的,在前面的onAttach方法中创建了mSearchFeatureProvider对象: 下面看看updateIndexAsync方法的具体内容: ==packages\apps\settings\src\com\android\settings\search\SearchFeatureProviderImpl.java == 在updateIndexAsync中调用了getIndexingManager的indexDatabase方法,getIndexingManager返回的是mDatabaseIndexingManager对象: 就是说,最后调用的是DatabaseIndexingManager的indexDatabase方法 ==packages\apps\settings\src\com\android\settings\search\DatabaseIndexingManager.java == 在方法中启动了一个异步任务: 它在doInBackground中,相当于后台执行的方法是performIndexing 在performIndex中首先找到所有配置android.content.action.SEARCH_INDEXABLES_PROVIDER的provider: \frameworks\base\core\java\android\provider\SearchIndexablesContract.java addIndexablesFromRemoteProvider 添加要搜索的app的设置项
addNonIndexablesKeysFromRemoteProvider 添加不需要设置到快速搜索的设置项
updateDatabase 将数据更新到数据库之中
来看看addIndexablesFromRemoteProvider方法: 在上面的方法中,主要做了下面几件事: 1 .根据包名创建对应包的context对象 2 .根据authority创建指定的Uri 3 .通过context对象查找对应的Provider的数据 注意 :所有的要被列入搜索项的所在的APP的Provider都要继承SearchIndexablesProvider,而SearchIndexablesProvider继承ContentProvider 下面初始化要添加到数据库里的数据: 先获得指定包的ContentResolver,然后解析Cursor数据添加到mDataToProcess对象的dataToUpdate属性中: dataToUpdate是一个list,“public List dataToUpdate” 数据加载完以后然后回到performIndexing,现在mDataToProcess中有数据,通过updateDatabase()方法把数据添加到快速搜索的数据库中 然后调用addDataToDatabase方法: 调用了indexOneSearchIndexableData方法: indexOneSearchIndexableData中有两种方式添加到数据库中,接下来看看indexOneResource 可以看到如果sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID>如果为真,就是能够获取到搜索项的xml,就可以直接调用indexFromResource 方法进行解析xml,不然就调用indexFromProvider方法: 可以发现在这里面获取到要解析的xml文件后,也是调用indexFromResource来进行解析xml文件的,现在来看看indexFromResource的具体内容: 在indexFromResource解析布局: 解析完布局后调用updateOneRowWithFilteredData–> updateOneRow()方法添加到数据库 此方法最终将解析的数据更新至数据库 最后再回到performIndexing方法中,可以看到一个明显数据库相关的类IndexDatabaseHelper 这个数据明显和搜索索引相关的数据库,search_index.db 数据库的prefs_index表格中存放的就是搜索的设置选项。数据库路径 :/data/user_de/0/com.android.settings/databases/search_index.db 注意:该数据库的初始化不是在开机的时候进行的,在你第一次点进Settting搜索的时候回初始化一次,但是你再次点击进去不会再次初始化
如何添加或删除一个快速搜索
这涉及到了一个组装数据的类SearchIndexableResources.java 在添加一个快速搜索的时候有两种方式 一种是在新建SearchIndexableResource对象的时候,传入布局文件,如 DateTimeSettings.java \packages\apps\settings\src\com\android\settings\DateTimeSettings.java 看到在创建SearchIndexableResource对象时候传入了R.xml.date_time_prefs文件 还有一种是“ NO_DATA_RES_ID”的,表示搜索匹配项里没有要解析的XML文件,在你添加好自己的写的设置项以后,需要在自己的文件里面创建SearchIndexProvider 的变量SEARCH_INDEX_DATA_PROVIDER,并继承BaseSearchIndexProvider内部类,然后重写getXmlResourcesToIndex,getNonIndexableKeys().等方法: 然后在SearchIndexableResources.java里面添加上面你写的文件: 第一个参数,类名;第二个参数,表示没有要加载的配饰文件;第三个参数,图标 要删除setting里面的快速搜索的话,在上面添加的两个方法,任意删除一个都可以,不过一般是在类的getNonIndexableKeys方法里面添加要移除的key packages/apps/Settings/src/com/android/settings/accessibility/AccessibilitySettings.java 有时候仅仅移除这里还不够,因为有些快速搜索还被添加到了AccessibilitySettings.java类中,此时也需要在AccessibilitySettings.java类的getNonIndexableKeys()方法添加要移除的key
参考:https://blog.csdn.net/qq_34149526/article/details/83378184
|