我对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
答案 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