对RecyclerView的View的WeakReference永远不会破坏?

时间:2016-11-17 15:53:56

标签: java android android-asynctask garbage-collection android-recyclerview

我对asynctask中的recyclerview视图有一个弱引用(该任务加载要在视图中显示的图像)。通常(如果我使用listview)gc在消失时收集视图,因此任务不会使用它,但在我的情况下(使用recyclerview),gc永远不会收集视图,因此任务还没有指向视图的弱引用,现在有一个新角色(另一个图像显示)。我该如何解决?我对这种情况有所了解吗?

谢谢!

我希望你明白,虽然英语不是我的母语......

修改 这是AsyncTask的代码:

class LoadPictureTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> mImageViewReference;
    private final int mImageSize;

    LoadPictureTask(ImageView imageView, int imageSize) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        mImageViewReference = new WeakReference<>(imageView);
        mImageSize = imageSize;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String path = params[0];
        return decodeSampledBitmapFromFile(path, mImageSize, mImageSize);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (mImageViewReference.get() != null && bitmap != null) {
            final ImageView imageView = mImageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
...
}

我担心在onPostExecute中我使用生成的位图(一个可回收的位图)设置另一个imageview

1 个答案:

答案 0 :(得分:0)

所以我测试了上面的案例,实际上这些观点的引用完全被滥用了。 AsyncTask将图像放到错误的视图中,一切都搞砸了。 我通过从ViewHolder保存指向AsyncTask的指针解决了这个问题,然后在onBindViewHolder中我取消了之前执行的AsyncTask并禁用了视图的可见性,直到它被新的AsyncTask再次设置为可见。

该代码将澄清我的意图:

package com.teamagam.dailyselfie;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ImageView;

import java.lang.ref.WeakReference;

class LoadPictureTask extends AsyncTask<String, Void, Bitmap> {
    private final WeakReference<ImageView> mImageViewReference;
    private final int mImageSize;

    LoadPictureTask(ImageView imageView, int imageSize) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        mImageViewReference = new WeakReference<>(imageView);
        mImageSize = imageSize;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String path = params[0];
        return decodeSampledBitmapFromFile(path, mImageSize, mImageSize);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (mImageViewReference.get() != null && bitmap != null) {
            final ImageView imageView = mImageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
                imageView.setVisibility(View.VISIBLE);
            }
        }
    }

    private static Bitmap decodeSampledBitmapFromFile(String path, int requiredWidth, int requiredHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateSampleSize(options, requiredWidth, requiredHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

    private static int calculateSampleSize(Options options, int requiredWidth, int requiredHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int sampleSize = 1;

        if (height > requiredHeight || width > requiredWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest sampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / sampleSize) >= requiredHeight
                    && (halfWidth / sampleSize) >= requiredWidth) {
                sampleSize *= 2;
            }
        }

        return sampleSize;
    }
}

当然是AsyncTask的代码:

left(EMP_CLass_9_descr, isnull(nullif(charindex(':', REPLACE(EMP_CLass_9_descr,' ','')),0) - 1,8000)) As TM_NAME
相关问题