创建异步的ContentProvider的动作条搜索查看 [英] Create asynchronous ContentProvider for Actionbar SearchView
问题描述
我在我的动作条一个搜索查看该连接用的ContentProvider给搜索建议。这些建议不是来自一个DB(像往常一样ContentProvider的),但是从一个Web服务。这就是为什么我要处理的ContentProvider的光标asyncronously。我的code工作至今,但搜索建议总是一个字母幕后黑手:
我输入后的
,我得到了previous所有结果的搜索=> 日
我输入后他们
,我得到了previous所有结果的搜索=> 的
我怎么能告诉搜索查看光标在有新的结果吗?我看着ContentObserver和ContentResolver的()。有NotifyChange(),但他们是不是真的有可能在搜索查看的范围内使用。
下面是我的code为止。最重要的部分是在onResponse-回调的ContentProvider的。我创建了一个新的MatrixCursor并用它来重写成员MatrixCursor。
AutocompleteSuggestionProvider延伸的ContentProvider
@覆盖
公共光标查询(最终开放的URI,字符串[]投影,选择字符串,字符串[] selectionArgs两个,串排序顺序){
查询字符串= selectionArgs两个[0];
mNetworkHelper.startAutoCompleteRequest(
selectionArgs两个[0],
SuggestionCategory.EVERYTHING,
新Response.Listener< AutoCompleteResponse>(){
/ **
*这是回调对于一个成功的Web服务请求
* /
@覆盖
公共无效onResponse(AutoCompleteResponse响应){
MatrixCursor nCursor =新MatrixCursor(SEARCH_SUGGEST_COLUMNS,10);
名单<字符串>建议= response.getResults();
// transfrom建议MatrixCursor
的for(int i = 0; I< suggestions.size()及和放大器;我小于10;我++)
nCursor.addRow(新的String [] {将String.valueOf(i)中,suggestions.get(ⅰ)});
}
//更新游标
mAsyncCursor = nCursor;
}
},
/ **
*这是回调的errornous Web服务请求
* /
新Response.ErrorListener(){
@覆盖
公共无效onErrorResponse(VolleyError错误){
Toast.makeText(的getContext(),Fehler,Toast.LENGTH_SHORT).show();
}
}
);
返回mAsyncCursor;
}
AndroidManifest
<活动
机器人:名称=。activities.MainActivity
机器人:标签=@字符串/ APP_NAME
机器人:launchMode =singleTop
>
<意向滤光器>
<作用机器人:名称=android.intent.action.MAIN/>
<类机器人:名称=android.intent.category.LAUNCHER/>
&所述; /意图滤光器>
<意向滤光器>
<作用机器人:名称=android.intent.action.SEARCH/>
&所述; /意图滤光器>
<元数据的android:MainActivity:NAME =android.app.default_searchable机器人值= />
<元数据的android:NAME =android.app.searchable安卓资源=@ XML /搜索/>
< /活性GT;
<供应商
机器人:名称=。provider.AutocompleteSuggestionProvider
机器人:当局=my.package.provider.AutocompleteSuggestion
机器人:出口=FALSE/>
searchable.xml
< XML版本=1.0编码=UTF-8&GT?;
<可搜索的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:标签=@字符串/ APP_NAME
机器人:提示=@字符串/ search_hint
机器人:searchSettingsDescription =@字符串/ search_settings
机器人:searchSuggestAuthority =my.package.provider.AutocompleteSuggestion
机器人:searchSuggestIntentAction =android.intent.action.VIEW
机器人:?searchSuggestSelection =
机器人:searchSuggestThreshold =2>
< /搜索>
我找到了解决办法。最重要的是要知道IST一个的ContentProvider的查询方法没有在UI线程上运行。因此,我们可以做一个同步的HTTP调用。由于每一个理智的人使用凌空这些日子里,你必须做这个调用是这样的:
字符串URL = NetworkHelper.buildRequestUrl(selectionArgs两个[0],SuggestionCategory.EVERYTHING,RequestType.AUTOCOMPLETE);
RequestFuture< JSONArray>未来= RequestFuture.newFuture();
JsonArrayRequest请求=新JsonArrayRequest(URL,未来,未来的);
。mNetworkHelper.getRequestQueue()加(要求);
//这不会在UI线程上运行,所以我们可以做一个同步的HTTP请求
尝试 {
JSONArray建议的Future.get =();
MatrixCursor resultCursor =新MatrixCursor(SEARCH_SUGGEST_COLUMNS,10);
的for(int i = 0; I< suggestions.length()及和放大器;我小于10;我++){
resultCursor.addRow(新的String [] {将String.valueOf(i)中,suggestions.get(ⅰ)的ToString()});
}
返回resultCursor;
}赶上(InterruptedException异常E){
e.printStackTrace();
}赶上(为ExecutionException E){
e.printStackTrace();
}赶上(JSONException E){
e.printStackTrace();
}
这下,一切工作正常。
I have a SearchView in my ActionBar which is connected with a ContentProvider to give search suggestions. These suggestions do not come from a DB (as usual with ContentProvider), but from a web service. That's why I have to handle the Cursor of the ContentProvider asyncronously. My code works so far, but the search suggestions are always one letter "behind":
After I enter "the"
, I get all results from the previous search => "th"
After I enter "they"
, I get all results from the previous search => "the"
How can I tell the SearchView that the Cursor has new results in it? I looked into ContentObserver and ContentResolver().notifyChange(), but they are not really possible to use in context of the SearchView.
Here's my code so far. The important part is in the onResponse-callback of the ContentProvider. I create a new MatrixCursor and use it to override the member MatrixCursor.
AutocompleteSuggestionProvider extends ContentProvider
@Override
public Cursor query(final Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String query = selectionArgs[0];
mNetworkHelper.startAutoCompleteRequest(
selectionArgs[0],
SuggestionCategory.EVERYTHING,
new Response.Listener<AutoCompleteResponse>() {
/**
* This is the callback for a successful web service request
*/
@Override
public void onResponse(AutoCompleteResponse response) {
MatrixCursor nCursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 10);
List<String> suggestions = response.getResults();
// transfrom suggestions to MatrixCursor
for (int i = 0; i < suggestions.size() && i < 10; i++)
nCursor.addRow(new String[]{String.valueOf(i), suggestions.get(i)});
}
// update cursor
mAsyncCursor = nCursor;
}
},
/**
* This is the callback for a errornous web service request
*/
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), "Fehler", Toast.LENGTH_SHORT).show();
}
}
);
return mAsyncCursor;
}
AndroidManifest
<activity
android:name=".activities.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.default_searchable" android:value=".MainActivity" />
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
</activity>
<provider
android:name=".provider.AutocompleteSuggestionProvider"
android:authorities="my.package.provider.AutocompleteSuggestion"
android:exported="false" />
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:searchSettingsDescription="@string/search_settings"
android:searchSuggestAuthority="my.package.provider.AutocompleteSuggestion"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestSelection=" ?"
android:searchSuggestThreshold="2" >
</searchable>
I found the solution. The most important thing to know ist that the query-method of a ContentProvider does NOT run on the UI-thread. Therefore we can do a synchronous HTTP call. Since every sane person uses Volley these days you have to do this call like this:
String url = NetworkHelper.buildRequestUrl(selectionArgs[0], SuggestionCategory.EVERYTHING, RequestType.AUTOCOMPLETE);
RequestFuture<JSONArray> future = RequestFuture.newFuture();
JsonArrayRequest request = new JsonArrayRequest(url, future, future);
mNetworkHelper.getRequestQueue().add(request);
// this does not run on the UI thread, so we can make a synchronous HTTP request
try {
JSONArray suggestions = future.get();
MatrixCursor resultCursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 10);
for (int i = 0; i < suggestions.length() && i < 10; i++) {
resultCursor.addRow(new String[]{String.valueOf(i), suggestions.get(i).toString()});
}
return resultCursor;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
This way everything works fine.
这篇关于创建异步的ContentProvider的动作条搜索查看的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!