I need to be able to MANAGER some requests with OKHTTP, using the Google Places AutoComplete
to receive some predictions by typing the Address. The Problem is Each time that I insert a CHAR it will make a new request but at the same time I need to cancel the previous one! Ex : New York City = 13 Requests at the same time! So I'm using a single instance of Call
trying to cancel anything that has been requested but with no success. This is what I did!
Address.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if(Address.getText().toString().length() > 3){
_Address = Address.getText().toString();
if(call != null){
call.cancel();
}
Request request = new Request.Builder()
.url(getPlaceAutoCompleteUrl(_Address))
.addHeader("content-type", "application/json")
.addHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
.build();
call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, final Response response) throws IOException {
final String result = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("Response",result);
PlacePredictions place = null;
try {
place = LoganSquare.parse(result,PlacePredictions.class);
} catch (IOException e) {
e.printStackTrace();
}
if(autoCompleteAdapter == null){
autoCompleteAdapter = new AutoCompleteAdapter(CustomPlaces.this);
recyclerView.setAdapter(autoCompleteAdapter);
autoCompleteAdapter.Add(place.getPlaces());
}else {
autoCompleteAdapter.Clear();
autoCompleteAdapter.Add(place.getPlaces());
autoCompleteAdapter.notifyDataSetChanged();
}
}
});
}
public void onFailure(Call call, IOException e) {
//fail();
}
});
}else {
if(autoCompleteAdapter != null){
autoCompleteAdapter.Clear();
}
}
}
I check if the call
object is null and cancel the request but still keeps coming!
What about the following:
//Set tags for your requests when you build them:
Request request = new Request.Builder().
url(url).tag("requestKey").build();
//When you want to cancel:
//A) go through the queued calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().queuedCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
//B) go through the running calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().runningCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
Delay request to server and post it only if input didn't changed for the timeout (1000 ms, adjust for better feel). You can add cancelation method to GetHintsRequest
...
Address.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (s.length() < 3) {
if (autoCompleteAdapter != null) {
autoCompleteAdapter.Clear();
}
return;
}
GetHintsRequest request = new GetHintsRequest(s.toString(), new GetHintsRequest.GetHintsCallback() {
@Override
public boolean isRequestNotChanged(String oldRequest) {
return Address.getText().toString().equals(oldRequest);
}
@Override
public void onGotHints(String request, PlacePredictions predictions) {
if (autoCompleteAdapter == null) {
autoCompleteAdapter = new AutoCompleteAdapter(CustomPlaces.this);
recyclerView.setAdapter(autoCompleteAdapter);
autoCompleteAdapter.Add(place.getPlaces());
} else {
autoCompleteAdapter.Clear();
autoCompleteAdapter.Add(place.getPlaces());
autoCompleteAdapter.notifyDataSetChanged();
}
}
});
request.postCheck();
}
});
...
public class GetHintsRequest {
private static final long TIMEOUT_MS = 1000; // timeout
private final String requestText;
private final GetHintsCallback callback;
// android.os.Handler, can be used to post and delayed post to main thread. activity.runOnUiThread uses it
private final Handler handler = new Handler(Looper.getMainLooper());
public GetHintsRequest(String requestText, GetHintsCallback callback) {
this.requestText = requestText;
this.callback = callback;
}
public void postCheck() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (callback.isRequestNotChanged(requestText)){
execute();
}
}
}, TIMEOUT_MS);
}
public void execute() {
Request request = new Request.Builder()
.url(getPlaceAutoCompleteUrl(_Address))
.addHeader("content-type", "application/json")
.addHeader("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; google_sdk Build/MR1) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
.build();
call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, final Response response) throws IOException {
final String result = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
Log.d("Response", result);
PlacePredictions place = null;
if (callback.isRequestNotChanged(requestText)) {
try {
place = LoganSquare.parse(result, PlacePredictions.class);
} catch (IOException e) {
e.printStackTrace();
return;
}
callback.onGotHints(requestText, place);
}
}
});
}
public void onFailure(Call call, IOException e) {
//fail();
}
});
}
public interface GetHintsCallback {
boolean isRequestNotChanged(String oldRequest);
void onGotHints(String request, PlacePredictions predictions);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With