在Android 5.0中增加了设置选项搜索功能。当你进入到设置菜单后,可以点击右上角的放大镜图标,它会在每个设置界面中出现,你可以在里面寻找想要设置的内容。虽然不能做到百分之百准确,但是至少还是提供了一些方便。
下文简单介绍了在我们搜索输入第一个字符开始,搜索功能执行的流程。
在SettingsActivity被创建时,SettingsSearchIndexablesProvider也同时被创建出来提供查询数据.需要查询的资源通过xmlresources来获取,SearchIndexableResources里定义了一个staitic块,来声明从哪些xml文件里获取查询条码的资源。这个数据只在首次创建被初始化一次,初始化后将被插入到数据库,如果代码有修改xml资源,需恢复出厂设置重新加载xml资源。
public Cursor queryXmlResources(String[] projection) {
MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
Collection<SearchIndexableResource> values = SearchIndexableResources.values();
for (SearchIndexableResource val : values) {
Object[] ref = new Object[7];
ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className;
ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId;
ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = null; // intent action
ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = null; // intent target package
ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
cursor.addRow(ref);
}
return cursor;
}
数据库的创建主要就用到了SettingsSearchIndexablesProvider,SearchIndexableResources,IndexDatabaseHelper这三个类。下面介绍查询过程。
查询的主要界面是在SearchResultsSummary.java这个文件里来处理的,在oncreate方法里,我们需要把得到的数据插入到listview里,搜索建议,处理与搜索结果类似,我们主要看搜索结果的处理:
mResultsAdapter = newSearchResultsAdapter(getActivity());
mSuggestionsAdapter =new SuggestionsAdapter(getActivity());
在输入第一个字符以后,SearchResultsSummary会执行onQueryTextChange,根据输入的字符信息,updateSearchResults会被调用来更新搜索结果。因输入每个字符都自动匹配搜索结果给用户选择,所以重新建了UpdateSearchResultsTask(继承自AsyncTask)这个task来处理搜索匹配。根据输入的字符信息(mQuery)去search_index.db(IndexDatabaseHelper定义)里查询字串信息:
protected Cursor doInBackground(String... params) {
returnIndex.getInstance(getActivity()).search(params[0]);
}
Search 首先会得到数据库再进行查询:
public Cursor search(String query) {
final SQLiteDatabase database = getReadableDatabase();
final Cursor[] cursors = new Cursor[2];
final String primarySql = buildSearchSQL(query, MATCH_COLUMNS_PRIMARY, true);
Log.d(LOG_TAG, "Search primary query: " + primarySql);
cursors[0] = database.rawQuery(primarySql, null);
// We need to use an EXCEPT operator as negate MATCH queries do not work.
StringBuilder sql = new StringBuilder(
buildSearchSQL(query, MATCH_COLUMNS_SECONDARY, false));
sql.append(" EXCEPT ");
sql.append(primarySql);
final String secondarySql = sql.toString();
Log.d(LOG_TAG, "Search secondary query: " + secondarySql);
cursors[1] = database.rawQuery(secondarySql, null);
return new MergeCursor(cursors);
}
然后的事情就由IndexDatabaseHelper来处理:
private SQLiteDatabasegetReadableDatabase() {
returnIndexDatabaseHelper.getInstance(mContext).getReadableDatabase();
}