【Android】IllegalArgumentException: You cannot start a load for a destroyed activity

  • Post author:
  • Post category:其他


做首页展示的时候,会有一个幻灯片的效果(也叫轮播图),github上有一个现成的框架,叫

banner,点我直达github


Android广告图片轮播控件,支持无限循环和多种主题,

可以灵活设置轮播样式、动画、轮播和切换时间、位置、图片加载框架等!

这个框架中会用到Glide

public class GlideImageLoader implements ImageLoader {
    @Override
    public void displayImage(Context context, Object path, ImageView imageView) {
        /**
          常用的图片加载库:

          Universal Image Loader:一个强大的图片加载库,包含各种各样的配置,最老牌,使用也最广泛。      
          Picasso: Square出品,必属精品。和OkHttp搭配起来更配呦!          
          Volley ImageLoader:Google官方出品,可惜不能加载本地图片~          
          Fresco:Facebook出的,天生骄傲!不是一般的强大。         
          Glide:Google推荐的图片加载库,专注于流畅的滚动。
         */

        Glide.with(context).load(path).into(imageView);
        or
        Picasso.with(context).load(path).into(imageView)
        ......
    }
}

我在使用的时候,遇到了一个比较极端的bug,我的网络环境比较差,打开apk后,轮播图还没有加载出图片,然后我就点返回退出程序,有一定概率会发生

beng

,然后查看控制台,报了个

IllegalArgumentException: You cannot start a load for a destroyed activity

,凭我的三脚猫的翻译能力,觉得这是“你不能在一个死Activity中加载数据什么哒”。

为什么会出现这个bug呢,因为Glide是一个网络请求, 会在子线程中进行网络请求,我刚进入程序,Glide还正在子线程中请求数据,这是我就把MainActivity干掉了(onDestroy),Glide没有提前中止请求,这时,我有两个想法。

  1. 主线程都死了,你子线程还请求数据,这不是闹着玩的吗!子线程不能脱离主线程单独存在。
  2. 主线程死了,子线程这时就算能成功加载数据,接下来数据给谁,这个接下来应该是空指针吧。

第2个想法肯定是不会出现的。那么如何针对第1种情况采取对应措施呢,很简单,在MainActivity Destroy之前先中止Glide请求,代码如下:

import com.bumptech.glide.util.Util;

private Context mContext = this;

@Override
    public void onDestroy() {
        super.onDestroy();
        if (Util.isOnMainThread()) {
            Glide.with(mContext).pauseRequests();
        }
    }

当然,为了稳妥起见,在使用Glide的时候,加上个判断条件,你们看着加吧。

public class GlideImageLoader implements ImageLoader {
    @Override
    public void displayImage(Context context, Object path, ImageView imageView) {
        if (Util.isOnMainThread()) {
            Glide.with(context).load(path).into(imageView);
        }
    }
}

我可能要推翻我之前的结论了,但我还没得出结论,先补充个重要的发现:

Glide 的 with 方法不光接受 Context,还接受 Activity 和 Fragment,Context 会自动的从他们获取,同时将 Activity/Fragment 作为 with()参数的好处是:图片加载会和 Activity/Fragment 的生命周期保持一致,比如 Paused 状态在暂停加载,在 Resumed 的时候又自动重新加载。

后来发现一个哥们写了一个解决方法,点击查看:

https://blog.csdn.net/loners_/article/details/73521968



版权声明:本文为yingpaixiaochuan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。