gpt4 book ai didi

java - 从 AsyncTask 中设置新位图的引用

转载 作者:行者123 更新时间:2023-11-30 04:05:56 24 4
gpt4 key购买 nike

这可能更像是一个 Java 问题而不是 Android 问题,但我无法检索在 AsyncTask 中创建的位图以存储在另一个类( Activity )中,以便我可以在使用完后回收它它。

AsyncTask 在 doInBackground() 中创建位图,并在 onPostExecute() 中将其设置为 ImageView 的位图,ImageView 通过构造函数传入。但完成后我希望在 Activity 中可以访问位图。 Activity 有一个 ImageViews 的 ArrayList 和另一个 Bitmaps,但是由于 AsyncTask 创建了一个新的 Bitmap,我找不到一个简单的方法来在 Activity 的 Bitmaps ArrayList 中获取这个新对象。目前,我通过将 ArrayList 连同列表中的索引传递给 AsyncTask 构造函数来使其工作,而 doInBackground 只是将数组中的条目设置为新创建的位图。

不过我不喜欢这个解决方案,因为我希望能够将这个 AsyncTask 用于不同的事情,也许在 Activity 没有位图 ArrayList 的情况下。而且我不能简单地给 AsyncTask 构造函数一个 Bitmap,因为 Java 按值传递引用,将它设置为一个新的 Bitmap 对象将不允许调用者访问。

我怎样才能更优雅地做到这一点?

这是相关代码。为清楚起见,省略了与此问题无关的行。

public class LoadCachedImageTask extends AsyncTask<String, Void, Void> {
private Context context;
private ImageView image;
private ArrayList<Bitmap> bitmaps;
int index;

public LoadCachedImageTask(Context context, ImageView image, ArrayList<Bitmap> bitmaps, int index) {
this.context = context;
this.image = image;
this.bitmaps = bitmaps;
this.index = index;
}

protected Void doInBackground(String... urls) {
String url = urls[0];
Bitmap bitmap = null;

// Create the bitmap
File imageFile = new File(context.getCacheDir(), "test");
bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());

// Set the bitmap to the bitmap list
bitmaps.set(index, bitmap);

return null;
}

protected void onPostExecute(Void arg) {
// Display the image
image.setImageBitmap(bitmaps.get(index));
}

protected void onCancelled() {
if (bitmaps.get(index) != null) {
bitmaps.get(index).recycle();
bitmaps.set(index, null);
}
}
}

这是一个使用它的示例 Activity。

public class SampleActivity extends Activity {
private ArrayList<ImageView> images;
private ArrayList<Bitmap> bitmaps;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
images = new ArrayList<ImageView>();
bitmaps = new ArrayList<Bitmap>();
int numImages = 15;

// Create the images and bitmaps
for (int i = 0; i < numImages; i++) {
images.add(new ImageView(this));
bitmaps.add(null);
}

// Load the bitmaps
for (int i = 0; i < numImages; i++) {
new LoadCachedImageTask(this, images.get(i), bitmaps, i).execute("http://random.image.url");
}
}
}

我没有测试过上面的代码,所以它可能无法工作,但我认为它明白了要点。

最佳答案

据我了解,您正在尝试将大量位图异步加载到大量 ImageViews 中。我认为这可以通过单个 AsyncTask 类来完成,您可以为每个 ImageView 多次使​​用该类。

你的 AsyncTask 应该是这样的:

  public class LoadCachedImageTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> mImgView;

public LoadCachedImageTask(ImageView image) {
mImageView = new WeakReference<ImageView>(image);
}

protected Void doInBackground(String... urls) {
if(urls == null || urls.length < 1)
return;

// Create the bitmap
final Bitmap bitmap = BitmapFactory.decodeFile(url);

return bitmap;
}

protected void onPostExecute(Bitmap bmp) {
// Display the image
if(bmp != null) {
final ImageView imageView = (ImageView) mImgView.get();
if(imageView != null) // needed in case the weakreference is removed
imageView.setImageBitmap(bmp);
}
}

然后用这样的东西填充你的 ImageViews 数组:

for(ImageView imgView : images) {
(new LoadCachedImageTask<String, Void, Bitmap>)(imgView).execute(getBitmapUrl());
}

for 循环将遍历每个 ImageView 引用并将其传递给全新的 AsyncTask 引用。然后它将使用给定的 url 执行 AsyncTask 到您需要的任何位图。只要 ImageView 存在,asynctask 就会保留对 ImageView 的引用。如果由于某种原因,您的 ImageView 被销毁,位图仍会加载,然后立即被丢弃。

关于java - 从 AsyncTask 中设置新位图的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11677895/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com