您的位置:首页 > 移动开发 > Android开发

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

2016-11-04 18:52 627 查看
做首页展示的时候,会有一个幻灯片的效果(也叫轮播图),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没有提前中止请求,这时,我有两个想法。

主线程都死了,你子线程还请求数据,这不是闹着玩的吗!子线程不能脱离主线程单独存在。

主线程死了,子线程这时就算能成功加载数据,接下来数据给谁,这个接下来应该是空指针吧。

第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 的时候又自动重新加载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐