Pregunta

I'm trying to implement search autocompletion with android-query library

I have callback instance in my activity:

Callback:

class SearchCompleteCallback extends AjaxCallback<ItemSearchResult> {
    public void callback(String url, ItemSearchResult searchResult, AjaxStatus status) {
            Log.d("SCB", String.format("Url:%s\n  Msg: %s\n  Code: %s\n  Error: %s",
                                       url,
                                       status.getMessage(),
                                       status.getCode(),
                                       status.getError()));
            if (searchResult != null) {
                Log.d("SCB", String.format("Status: %s\n  Val: %s",
                                           searchResult.getStatus(),
                                           searchResult.getInnGroup().getItems()));
                
                updateSearchResult(searchResult);
            }
            else {
                Log.w("SCB", "Ajax failed");
                
            }
    }
}

Search routine, that called on text change:

private void doSearch(String query) {
    ppApi.getSearchResult(query, searchCompleteListener);
}  

and

APIClass

public class PPServerApi {
    private AQuery aq;
    private GsonTransformer transformer;
    
    private static class GsonTransformer implements Transformer{
        public <T> T transform(String url, Class<T> type, String encoding, byte[] data, AjaxStatus status) {
            Gson g = new Gson();
            return g.fromJson(new String(data), type);
        }
    }
    
    public PPServerApi(AQuery newAq){
        aq = newAq;
        transformer = new GsonTransformer();
        AQUtility.setDebug(true);
        AjaxCallback.setTransformer(transformer);
    }

    public void getSearchResult(String itemName, AjaxCallback<ItemSearchResult> cb){
            String url = "http://my.api.server/search?q=" + itemName;
            aq.ajax(url, ItemSearchResult.class, cb.header("content-type", "application/json"));
        }
}  

So, the question is how to abort old queries before sending new one ?
(I don't need result of old queries if text in search field changed)

I've tried to call searchCompleteListener.abort() in doSearch(), but it causes exception in next going query:

08-09 20:59:10.551: W/AQuery(6854): get:http://my.api.server/search?q=abc
08-09 20:59:10.551: W/AQuery(6854): creating http client
08-09 20:59:10.561: W/AQuery(6854): java.io.IOException: Aborted
08-09 20:59:10.561: W/AQuery(6854):     at com.androidquery.callback.AbstractAjaxCallback.httpDo(AbstractAjaxCallback.java:1569)
...  

so, i can't perform even single query in this case.

¿Fue útil?

Solución

There is no way of making android-query cancel an AJAX request once it has been started. You'll have to use another library, sorry.

What you can do is to check if the request has become obsolete when it finishes.

You could do that by checking if the URL matches the latest URL you requested for

if (searchResult != null && url.equals(latestRequestUrl)) {

(note, you'd have to let getSearchResult return the URL)

Otros consejos

You can use the droidQuery library instead. Using droidQuery, you can cancel all Ajax tasks using the call:

$.ajaxKillAll();

You can also perform your request with this:

$.ajax(new AjaxOptions().url(url).header("content-type", "application/json").type("json").dataType("GET").dataType("json").success(new Function() {
    @Override
    public void invoke($ droidQuery, Object... params) {
        JSONObject json = (JSONObject) params[0];
        //TODO handle json
    }
}).error(new Function() {
    @Override
    public void invoke($ droidQuery, Object... params) {
        AjaxError error = (AjaxError) params[0];
        Log.e("Ajax", "Error " + error.status + ": " + error.reason);
    }
}));

You can abort any aquery processing using this.

private AjaxCallback<String> ajaxCallback = new AjaxCallback<String>(){
        @Override
        public void callback(String url, String object, AjaxStatus status) {
               //do your processing with server response
                   processInformation(result);
        };
    };
   //on our previous code
   query.ajax(remoteUrl,String.class,ajaxCallback);

   public void cancelAquery(){
      //this statement does cancel the request i.e. we won't receive any information on callback method
     //ajaxCallback.async(null);  

     ajaxCallback.abort();
}

For more info, you can see this link https://laaptu.wordpress.com/tag/android-cancelling-aquery/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top