在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();
}