A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled()
periodically from doInBackground(Object[])
, if possible (inside a loop for instance.)
In your case, there is no loop in your doInBackground()
code. In fact it would be better if you turn it into a loop by reading the response stream buffered. This would be more performant and enable you to call isCancelled()
in the loop.
Example: Use ByteArrayOutputStream to read bytes in chunks and check isCancelled()
periodically in the loop.
protected Bitmap doInBackground(Object... params) {
try {
URL url = new URL(imageURL);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
input = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] byteChunk = new byte[4096];
int n;
while ( (n = input.read(byteChunk)) > 0 ) {
if(isCancelled()) {
return null;
}
baos.write(byteChunk, 0, n);
}
Bitmap myBitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try {
if (input != null)
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Of course you should keep a reference to your AsyncTask object to be able to call cancel method on it.
private ImageLoader loader;
...
...
loader = new ImageLoader();
loader.execute();
...
...
loader.cancel()