[英]WeakReference to a RecyclerView's View never breaks?
我在asynctask中對recyclerview的視圖有較弱的引用(該任務會加載要在視圖中顯示的圖像)。 通常情況下(如果我使用列表視圖),當gc消失時該視圖由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(一個回收的位圖)
因此,我測試了上述情況,確實完全濫用了視圖的引用。 AsyncTask將圖像放置在錯誤的視圖中,並且一切都被弄亂了。 我通過從ViewHolder保存指向AsyncTask的指針來解決此問題,然后在onBindViewHolder中取消了先前執行的AsyncTask並禁用了視圖的可見性,直到新AsyncTask將其設置為可見為止。
該代碼將闡明我的意圖:
package com.teamagam.dailyselfie;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
class PictureAdapter extends RecyclerView.Adapter<PictureAdapter.PictureViewHolder> {
private LayoutInflater mInflater;
private List<PictureInfo> mPictureInfoList;
PictureAdapter(Context context, List<PictureInfo> pictureInfoList) {
mInflater = LayoutInflater.from(context);
mPictureInfoList = pictureInfoList;
}
@Override
public PictureViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.layout_picture, parent, false);
return new PictureViewHolder(view);
}
@Override
public void onBindViewHolder(PictureViewHolder pictureViewHolder, int position) {
PictureInfo pictureInfo = mPictureInfoList.get(position);
pictureViewHolder.mTextView.setText(pictureInfo.fileName);
int imageSize = pictureViewHolder.mImageView
.getContext()
.getApplicationContext()
.getResources()
.getInteger(R.integer.activity_main_thumbnail_size);
if (null != pictureViewHolder.mLoadPictureTask) {
pictureViewHolder.mLoadPictureTask.cancel(true);
}
pictureViewHolder.mImageView.setVisibility(View.INVISIBLE);
pictureViewHolder.mLoadPictureTask = new LoadPictureTask(pictureViewHolder.mImageView, imageSize);
pictureViewHolder.mLoadPictureTask.execute(pictureInfo.path);
}
@Override
public int getItemCount() {
return mPictureInfoList.size();
}
class PictureViewHolder extends RecyclerView.ViewHolder {
ImageView mImageView;
TextView mTextView;
LoadPictureTask mLoadPictureTask;
PictureViewHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.ivItemListImage);
mTextView = (TextView) itemView.findViewById(R.id.tvItemListImage);
}
}
}
當然還有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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.