I want to cancel an AsyncTask
after a timeout if the task is still running and I want to cancel it immediately. Here is my code:
HttpURLConnection connection = null;
//GetRequestTask extends AsyncTask
final GetRequestsTask requestTask = new GetRequestsTask();
requestTask.execute(createUrl());
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d("myapp", "entered handler");
if (requestTask.getStatus() == AsyncTask.Status.RUNNING) {
Log.d("myapp", "entered cancelling");
requestTask.cancel(true);
connection.disconnect();
}
}
}, TIME_OUT);
As you can see, I am calling a HTTP
request in my AsyncTask
's doInBackground
method. and when I want to cancel the AsyncTask
I also disconnect the connection.
The problem is that when I call cancel(true)
and my app logs entered cancelling
, the AsynkTask
won't cancel immediately and will cancel with a minimum 10 to 20 seconds delay.
what should I do to cancel the task as soon as I call cancel?
UPDATE: This is my `AsyncTask code:
private class GetRequestsTask extends AsyncTask<URL, Void, JSONObject> {
@Override
protected void onPreExecute() {
Log.d("myapp", "entered onPreExecute");
mLoadingDialog.show();
}
@Override
protected JSONObject doInBackground(URL... urls) {
Log.d("myapp", "entered doInBackground");
try {
connection = (HttpURLConnection) urls[0].openConnection();
connection.setRequestProperty("Accept", "application/json");
int response = connection.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
try {
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
reader.close();
}
return new JSONObject(builder.toString());
}
else {
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
connection.disconnect();
}
return null;
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
Log.d("myapp", "entered onPostExecute");
mLoadingDialog.dismiss();
if (jsonObject == null) {
showNoInternetDialog();
}
else {
convertJSONtoArrayList(jsonObject);
mRequestArrayAdapter.notifyDataSetChanged();
mListView.smoothScrollToPosition(0);
}
}
@Override
protected void onCancelled() {
Log.d("myapp", "entered onCancelled");
mLoadingDialog.dismiss();
showNoInternetDialog();
}
The problem is that my timeout is 20 seconds, but onCancelled
is called after 35, 40 seconds.
From this question :
If you're doing computations:
If you're doing a HTTP request:
Additionally if you use some library to provide convenient requests, then I think it should have some cancel() method. For example, for retrofit there is such method.
So in this case like for 'If you're doing a HTTP request' section. you need to:
And one more alternative is rxJava. With help of this library you can create Observable for your request and save reference to its subscription. Then you just need to call savedSubscription.unsubscribe() and that's it.
Also, please, do not use Async tasks as inner classes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.