0

我正在阅读这篇文章http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ 以了解我手头的任务的细节。

我必须开始一项任务,从互联网上下载一张我将在每一行显示的图像。

我不明白以下代码如何工作(从我发布的文章链接复制)

   public View getView(int position, View convertView,
        ViewGroup parent) {
    ViewHolder holder;

    ...

    holder.position = position;

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

    return convertView;
}

private static class ThumbnailTask extends AsyncTask {
    private int mPosition;
    private ViewHolder mHolder;

    public ThumbnailTask(int position, ViewHolder holder) {
        mPosition = position;
        mHolder = holder;
    }

    @Override
    protected Cursor doInBackground(Void... arg0) {
        // Download bitmap here
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (mHolder.position == mPosition) {
            mHolder.thumbnail.setImageBitmap(bitmap);
        }
    }
}

private static class ViewHolder {
    public ImageView thumbnail;
    public int position;
}

现在我不明白的是 onPostExecute 中的 if 条件如何工作?. mHolder.position=mPosition 。在初始化任务时,这两个值都被赋予了任务。如果后面的视图甚至被回收,这对 AsyncTask 中的 mPosition 变量有何影响?该任务已经启动,例如 mPosition 值为 2 。

现在当视图被回收并且位置为 15 时,这将如何反映在以 mPosition = 2 启动的任务中?

请帮忙。

谢谢

4

1 回答 1

0

的构造函数ThumbnailTask有 2 个参数;一个原始类型位置和一个引用类型持有者。

   ThumbnailTask(int position, ViewHolder holder)

因此,位置参数永远保持其值不变(因为它是原始的)。例如,如果ThumbnailTask创建时使用 5 作为位置,那么对于该实例,它将始终为 5。但是 holder 参数是一个参考。如果它在某处/外部被更改,这将影响 ThumbnailTask​​ 中的值。

在您的列表示例中,您的问题最重要的部分已被删除(“...”部分显示在您共享页面上方的上一个示例中)。我从链接中得到它并在这里合并。现在你会更清楚。

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    // '...' parts starts
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.your_layout, null);

        holder = new ViewHolder();
        holder.text = (TextView) convertView.findViewById(R.id.text);

        convertView.setTag(holder);
    } else {
        holder = convertView.getTag();
    }
    holder.text.setText("Position " + position);
    // '...' parts ends

    holder.position = position;

    return convertView;
}

如您所见,在此部分中,如果 convertView 不为空,则不会再次创建持有者实例。但它的位置值发生了变化。因此,此更改对之前创建的 ThumbnailTask​​ 实例具有相同的效果。

现在你的问题:

Now when the view is recycled and the position is 15 , how will this be reflected in the task initiated with mPosition = 2 ?

位置在启动时将始终保持相同的值。但是持有人正在 getView 方法中进行编辑。mHolder.position == mPosition如果持有人用于另一个列表行并且下载的位图将无用,那么将是错误的。

@Override
protected void onPostExecute(Bitmap bitmap) {
    if (mHolder.position == mPosition) {
        mHolder.thumbnail.setImageBitmap(bitmap);
    }
}

希望这可以帮助。

于 2013-10-27T13:42:04.127 回答