创建异步的ContentProvider的动作条搜索查看 [英] Create asynchronous ContentProvider for Actionbar SearchView

查看:135
本文介绍了创建异步的ContentProvider的动作条搜索查看的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的动作条一个搜索查看该连接用的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:机器人=htt​​p://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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆