阅读以下内容后,我想到了这个问题:Performance tips(特别是名为“异步加载”的部分)。基本上,他试图保存有关行的信息,以查看行是否已被回收,并且仅在行仍然可见时才设置下载的图像。这是他保存职位的方式:

holder.position = position;

new ThumbnailTask(position, holder)
        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);

其中ThumbnailTask​​构造函数为:
public ThumbnailTask(int position, ViewHolder holder) {
    mPosition = position;
    mHolder = holder;
}

然后在onPostExecute()中,执行前面提到的检查:
    if (mHolder.position == mPosition) {
        mHolder.thumbnail.setImageBitmap(bitmap);
    }

我只是看不到这如何产生任何结果。将Holder和位置同时在构造函数中设置为相同的值(holder中的位置与mPosition中的位置相同)。它们在AsyncTask期间不会更改(的确,位置可能会在getView()中发生变化,但是存储在AsyncTask中作为私有(private)成员的位置永远不会被操纵)。我在这里想念什么?

首先,保存位置似乎也不是一个好选择:我相信不能保证它是唯一的,如果我没记错的话,滚动后它会重置为0。我在想正确的方向吗?

最佳答案

背景(您可能知道这一点,但以防万一):适配器包含对象的集合,并使用这些对象中的信息来填充 View (每个 View 都是列表中的一个行项目)。 ListView 负责显示这些 View 。出于性能原因,ListView将回收不再可见的 View ,因为它们从列表的顶部或底部滚动。这是它的工作方式:

当ListView需要新 View 显示时,它将调用适配器的getView及其整数参数“position”,以指示它想查看的适配器集合中的哪个对象(位置只是从1到N -1的数字),其中N是适配器中对象的数量。

如果它具有不再可见的任何 View ,它将也将其中一个传递给适配器,如“convertView”。这表示“重用这个旧 View 而不是创建一个新 View ”。巨大的性能胜利。

本文中的代码将ViewHolder对象附加到它创建的每个 View ,该 View 除其他外还包含ListView请求的对象的位置。在文章的代码中,该位置与指向将包含图像的 View 中的字段的指针一起隐藏在ViewHolder内部。 ViewHolder作为标签附加到 View (一个单独的主题)。

如果 View 被回收以容纳不同的对象(位于不同的位置),则ListView将调用Adapter.getView(newPosition,oldView ...)本文中的代码会将新位置存储到附加到oldView的ViewHolder中。 (到目前为止是否有意义?),然后开始加载此新图像以放入 View 中。

现在,在本文中,它正在启动AsyncTask来检索应进入 View 的数据。此任务具有位置(来自getView调用)和保持器(来自oldView)。该位置告诉它请求了什么数据。持有人告诉它当前在该 View 中应显示哪些数据,以及一旦显示就将其放置在何处。

如果在AsyncTask仍在运行时 View 再次被回收,则持有人的位置将被更改,因此这些数字将不匹配,并且AsyncTask知道不再需要其数据。

这样更清楚了吗?

关于android - 异步加载图片,检查图片是否被回收,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18135452/

10-12 03:59