我正在处理图像下载程序,它是一个异步下载程序。每当需要在互联网上显示图像时我都会打电话
图像异步下载器(输入是目标图像视图,图像网址)
public class ImageLoader extends AsyncTask<Object, Void, Bitmap> {
private static String TAG = "ImageLoader";
public InputStream input;
public ImageView view;
public String imageURL;
@Override
protected Bitmap doInBackground(Object... params) {
try {
view = (ImageView) params[0];
imageURL = (String) params[1];
URL url = new URL(imageURL);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
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();
}
}
}
@Override
protected void onPostExecute(Bitmap result) {
if (result != null && view != null) {
view.setImageBitmap(result);
view.setBackgroundResource(android.R.color.transparent);
view.getBackground().setAlpha(255);
}
}
}
当我切换到特定标签时,我的应用程序的结构是一个tabhost,例如在第4部分,有一个gridview,它将触发imageloader asynctask
片段:
gridView.setAdapter(new GalleryAdapter(getActivity() , images));
适配器:
public class GalleryAdapter extends BaseAdapter {
private Context mContext;
public ArrayList<GalleryImage> images;
// Constructor
public GalleryAdapter(Context c, ArrayList<GalleryImage> _images) {
mContext = c;
images = _images;
}
@Override
public int getCount() {
return images.size();
}
@Override
public Object getItem(int position) {
return images.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if( convertView == null ){
convertView = (ImageView)new ImageView(mContext);
int size = (int)(Utility.getScreenWidth(mContext) / 3) - 1;
AbsListView.LayoutParams params = new AbsListView.LayoutParams(size, size);
convertView.setLayoutParams(params);
convertView.setBackgroundResource(android.R.color.darker_gray);
convertView.getBackground().setAlpha(204); // = 0.8 alpha
}
new ImageLoader().execute(convertView,images.get(position).thumbUrl);
return convertView;
}
}
我想知道在更改标签时有没有办法取消下载任务? (由于用户在完成所有下载之前都会离开选项卡,因此无需再下载)
答案 0 :(得分:2)
可以随时通过调用cancel(boolean)取消任务。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,onCancelled(Object)将在onPostExecute(Object)返回后调用,而不是doInBackground(Object[])。 为了确保尽快取消任务,您应该始终从isCancelled()
定期检查doInBackground(Object[])
的返回值,如果可能的话(例如在循环内)。
在您的情况下,doInBackground()
代码中没有循环。事实上,如果通过读取缓冲的响应流将其转换为循环会更好。这样性能更高,并且您可以在循环中调用isCancelled()
。
示例:使用ByteArrayOutputStream读取块中的字节,并在循环中定期检查isCancelled()
。
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();
}
}
}
当然,您应该保留对AsyncTask对象的引用,以便能够对其调用cancel方法。
private ImageLoader loader;
...
...
loader = new ImageLoader();
loader.execute();
...
...
loader.cancel()