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 になります。ただし、ホルダーパラメータは参考です。どこか/外部で変更されている場合、これは 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 が null でない場合、ホルダー インスタンスは再度作成されません。ただし、その位置の値は変更されます。したがって、この変更は、以前に作成された 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、ホルダーが別のリスト行に使用され、ダウンロードされたビットマップが役に立たない場合は false になります。

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

お役に立てれば。

于 2013-10-27T13:42:04.127 に答える