【问题标题】:Terminate the running download async task in android终止android中正在运行的下载异步任务
【发布时间】:2014-02-12 09:30:27
【问题描述】:

我正在开发一个图像下载器,它是一个异步下载器。每当需要在互联网上显示图像时,我都会调用它

图片异步下载器(输入目标imageview、图片url)

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;
    }
}

我想知道当我更改标签时有什么方法可以取消下载任务? (由于用户在所有下载完成之前离开标签,因此无需再下载)

【问题讨论】:

    标签: android asynchronous android-fragments android-asynctask tabwidget


    【解决方案1】:

    可以通过调用cancel(boolean) 随时取消任务。调用此方法将导致对isCancelled() 的后续调用返回true。调用此方法后,onCancelled(Object) 将在 doInBackground(Object[]) 返回后调用,而不是 onPostExecute(Object)为确保尽快取消任务,您应始终定期从doInBackground(Object[]) 检查isCancelled() 的返回值,如果可能(例如在循环内)。

    在您的情况下,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 对象的引用,以便能够对其调用取消方法。

        private ImageLoader loader;
        ...
        ...
        loader = new ImageLoader();
        loader.execute();
        ...
        ...
        loader.cancel()
    

    【讨论】:

    • 您介意提供一些更详细的代码示例吗?非常感谢
    猜你喜欢
    • 2023-01-30
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多