如何在Android的getView()函数中取消隐藏项中的AsyncTask执行?

5

我有一个问题:在ArrayAdapter的getView()函数中,我使用AsyncTask将图像加载到ImageView中。但是当该项不可见时(滚动listview),AsyncTask函数仍在加载图像。我想在项目不可见时禁用AsyncTask进程。有解决此问题的方法吗?

5个回答

2

这需要两个步骤。

1)意识到项目视图已经滚出屏幕(或由于其他原因不再使用)。

您可以使用setRecyclerListener()添加一个RecyclerListener对象,该对象将在要回收项目视图时通知您(onMovedToScrapHeap())。

2)实际上中止AsyncTask。

这取决于您实际执行的操作。如果执行的是HTTP请求(从描述中似乎是这样),则调用cancel(true)应该会导致中断并中止下载。

但是,在此之前,请考虑:如果正在下载图像并中断此过程,则意味着当您向上滚动时,它可能必须重新下载。也许更好的策略只是让下载完成,但如果已被重用,则不加载ImageView本身(您可以通过设置标记来检测它)。


0
如果您不使用RecyclerView,那么您也可以在getView()中执行以下操作。
        if(vH.thumb.getTag() != null)
            ((LoadImage) vH.thumb.getTag()).cancel(true);
        LoadImage loadImage =  new LoadImage(vH.thumb, context.getActivity());
        loadImage.execute(pic);
        vH.thumb.setTag(loadImage);

因此,您必须使用ViewHolder(=vH)进行工作。如果您正在下载可以取消下载本身的图像,则非常有用。 通过询问isCancelled(),您现在知道何时停止。

我知道这是一个老问题,但那个解决方案对我帮助很大。


0

您可以在图像加载时检查它是否仍然是应该显示的正确ListView项。如this answer所述,首先将路径存储为ImageView的标记,并在onPostExecute中进行检查:

protected void onPostExecute(Bitmap result) {
    if (!imv.getTag().toString().equals(path)) {
           /* The path is not same. This means that this
              image view is handled by some other async task. 
              We don't do anything and return. */
           return;
    }

    if(result != null && imv != null){
        imv.setVisibility(View.VISIBLE);
        imv.setImageBitmap(result);
    }else{
        imv.setVisibility(View.GONE);
    }
}

位图仍将完全加载。


0

1
只有在异步任务中的工作正在循环执行时,isCancelled() 才会有帮助,这样 isCancelled() 就可以被重复执行。我认为图像加载不涉及循环。 - faizal

-1
使用通用图像加载器。在类似的构建中,我使用


displayImage(URL, imageview);

这个库在getView中的作用是显示给定ImageView上的图像,速度非常快。您还可以缩小图像的大小以加快加载速度。该库还可以帮助您节省大量工作,并执行/跟踪许多异步任务。


亲爱的Aksoy,我尝试使用Universal Image Loader,但是当我滚动listview时,任务总是在前台运行。 - nguoitotkhomaisao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接