Android系统中大部分搜索功能的实现使用的是Android系统提供的SearchView控件,因此搜索是采用Android系统的Search Framework来实现的。下面对Search Framework简要分析:
用户提交查询后,Android系统构造一个Intent并把用户的查询内容放在这个Intent中。然后Android启动自定义的用来处理用户查询的Activity(SearchActivity),并把这个Intent发给该Activity。为了能够使用Android系统提供的Search Framework.需要以下几步:
1. Creating a Searchable Configuration
首先定义一个Searchable configuration,用于描述SearchView的一些属性,该描述文件按惯例通常命名为searchable.xml 并定义在/res/xml 目录下。
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:value="com.android.calendar.SearchActivity"
android:label="@string/app_label"
android:searchMode="showSearchLabelAsBadge"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:voiceLanguageModel="free_form"
android:searchSuggestAuthority="com.android.calendar.CalendarRecentSuggestionsProvider"
android:searchSuggestSelection=" ? "
android:imeOptions="actionSearch" >
</searchable>
只有android:label是必须的,一般定义为应用程序的名称。
2. Creating a Searchable Activity
一个”Searchable Activity”就是一个可以用来处理Search Query 的Activity。和一般的Activity没有太大分别。当用户提交查询后,Android会给这个“Searchable Activity”发送一个Intent包含有用户查询内容,同时这个Intent 含有ACTION_SEARCH action。
由于可以在任何一个Activity中使用SearchView,Android需要知道哪个Activity
是“Searchable Activity”,这就需要在AndroidManifest.xml中来定
义“SearchActivity”。
本例中定义为“SearchActivity”,它在AndroidManifest.xml中定义为:
<activity android:name="SearchActivity"
android:label="@string/search_title"
android:launchMode="singleTop"
android:theme="@style/CalendarTheme.WithActionBar"
android:windowSoftInputMode="stateAlwaysHidden"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
SearchActivity 需要在Intent-filter中指定android.intent.action.SEARCH,并在<meta-data>部分指定 searchable configuration (指向res/xml/searchable.xml)SearchActivity用来处理查询请求Intent的代码如下
...........
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query;
if (icicle != null &&
icicle.containsKey(BUNDLE_KEY_RESTORE_SEARCH_QUERY)) {
query =
icicle.getString(BUNDLE_KEY_RESTORE_SEARCH_QUERY);
} else {
query = intent.getStringExtra(SearchManager.QUERY);
}
initFragments(millis, query);
}
...........
private void initFragments(long timeMillis, String query) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
AgendaFragment searchResultsFragment = new AgendaFragment(timeMillis, true);
ft.replace(R.id.search_results, searchResultsFragment);
mController.registerEventHandler(R.id.search_results, searchResultsFragment);
ft.commit();
Time t = new Time();
t.set(timeMillis);
search(query, t);
}
...........
上述大概就是Android系统中Search Framework处理流程。