gpt4 book ai didi

android - 方向更改后未完成的 AsyncTask 中的 View 引用会发生什么情况?

转载 作者:行者123 更新时间:2023-11-30 01:48:24 25 4
gpt4 key购买 nike

请注意,此问题的灵感来自对 https://stackoverflow.com/a/33370816/519334 的评论.

我有一个属于 GridView 项目的 holder 类,它引用了一个 ImageView

public static class Holder {
ImageView mRowImage;
String mImageUrl;

// neccessary to cancel unfinished download
BitmapLoaderAsyncTask mDownloader;
}

相应的 GridItemAdapter 使用 AsyncTask 获取 GridItem 的图像

public class GridItemAdapter extends BaseAdapter {
@Override
public View getView(int position, ...) {
...
if (view == null) {
holder = ...
...
} else {
holder = (Holder) view.getTag();
}
...
// cancel unfinished mDownloader
if (holder.mDownloader != null) {
holder.mDownloader.cancel(false);
holder.mDownloader = null;
}
holder.mImageUrl = mImageUrls.get(position);
holder.mDownloader = new BitmapLoaderAsyncTask()
holder.mDownloader.execute(holder);
}
}

static class BitmapLoaderAsyncTask extends AsyncTask<Holder, Void, Bitmap> {
Holder mHolder;
protected Bitmap doInBackground(Holder... holders) {
mHolder = holders[0];
...
}
protected void onPostExecute(...) {
mHolder.mDownloader = null;
if (!isCancelled()) {
this.mHolder.mRowImage.setImageBitmap(image);
}
this.mHolder = null;
}
}

一条评论表明,方向更改后此代码可能存在问题。

场景

  • 网格处于横向模式
  • GridItemAdapter 启动 BitmapLoaderAsyncTask#1 以加载 Image1.jpg
    • 异步任务有 mHolder.mRowImage
  • 网格方向从横向模式变为纵向模式
  • BitmapLoaderAsyncTask#1 完成并调用 onPostExecute(..)
  • (!!!) 在 onPostExecute(..) 中更新图像 mHolder.mRowImage。由于 mHolder.mRowImage 不再存在,因为方向改变,所以应该会发生崩溃。

我有code similar to the described scenario到目前为止,我还没有遇到 (!!!) 崩溃。

我的问题

  • 还没有(!!!)崩溃只是巧合吗?
  • 是否有一个简单的解决方案来检查 onPostExecute(..) mHolder.mRowImage 不再有效?
  • 或者 Android 中有什么东西可以保护 AsyncTask

最佳答案

Since mHolder.mRowImage does not exist any more because orientation change so there should be a crash.

这是不正确的,所有线程都是 GC 根,并且您的 AsyncTask 持有对 View 对象的强引用(它在您的 Holder 中类)并且您的 View 对 Activity/Fragment/等有很强的引用。因此,只要您的 AsyncTask 正在运行,您的 Activity/Fragment/etc 就不会被正确地垃圾收集。它不会导致任何崩溃(因为 View 确实存在)但会发生内存泄漏并且结果将传递给旧的 Activity/Fragment/等。

但是,如果您确保正确取消了 AsyncTask,一切都会好起来的。但是如果你想 100% 确定你应该使用 WeakReferenceBitmapLoaderAsyncTask

中保存你的 Holder

@编辑

您现在取消任务的方式不正确。方向更改后,所有 View 将再次膨胀(在新的 Activity/Fragment/等中),因此 view.getTag 将始终为 null。

关于android - 方向更改后未完成的 AsyncTask 中的 View 引用会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33394184/

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