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

用Glide加载图片到Recyclerview中有时候只显示占位图的问题

2017-07-31 14:36 369 查看
转载请标注:http://blog.csdn.net/friendlychen/article/details/76436806

1、IllegalArgumentException: You cannot start a load for a destroyed activity

这是使用Glide加载图片经常遇到的问题,这个问题在我的《Android解决bug的思路:追本溯源》http://blog.csdn.net/friendlychen/article/details/73299095一文中做了深入分析,当时的分析是找到相应错误提示的源码:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private static void assertNotDestroyed(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
}
}


这里就是产生报错地方的源码,这里是抛出IllegalArgumentException异常,看源码可知抛出异常的条件有两个, 一个条件是Android版本号大于J,另一个条件activity.isDestroyed()都为真时,才抛出这个异常。现在Android版本号基本都是大约J了,而当我们activity销毁后,Glide还在工作,这时就抛出了这个异常了。也就是说当Activity会销毁了,则抛出了异常,为什么会这样呢?因为我们的Glide是有生命周期的,Glide.with()中传入的context参数就是代表了Glide生命周期,比如传入Activity的Context则当Activity销毁时,Glide应该停止加载数据,毕竟这时即使Glide加载了数据也没地方显示呀,这不是浪费流量吗。因此当Activity结束时,Glide也要停止加载数据。

最后得出的解决方法是尽量使用全局的生命周期,也就是Glide.with(context.getApplicaiontContext()).into(imageView);

2、用Glide加载图片显示在Recyclerview中结果有时候只显示占位图

这个跟业务场景有关,我们项目中加载图片比较多,在一个A Activity中用Glide加载图片在Recyclerview正常显示了图片,点击某个item后进去B Activity,B中继续用Glide加载图片,结果返回到A Activity,上下滑动Recyclerview时结果全部都是占位图。

花了大量的时间,发现我们在B Activity中的onDestroy方法中加入了
Glide.with(context.getApplicationContext()).pauseRequests();


这里的with()方法中传入的是全局Context,则当关闭Glide时,则相当于关闭了这个应用的Glide加载图片,于是A Activity中的Glide加载图片也关了。当Recyclerview中滑动时,本来应用是显示Glide缓存中的图片,结果关闭了Glide加载数据,就连缓存的图片都不能加载了,图片区域就显示了占位图。

这里可以在需要加载图片的地方及时加上Glide.with(context.getApplicationContext()).resumeRequests()

我们项目是在Recyclerview的滑动监听中判断是否滑动来决定是否启动Glide加载:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

switch (newState) {
case 0:
startGlide(true);
break;
case 1:
startGlide(true);
break;
case 2:
startGlide(false);
break;
}
}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

}
});


我们在Recyclerview中的滑动事件中进行监听,当暂停和拖拽滑动时开启Glide加载图片,当滑动后自然沉降状态时停止Glide,其中startGlide()中的代码是:

private boolean mAlreadyStart = true;//是否已经开启Glide加载图片
private void startGlide(boolean start) {
if (mAlreadyStart) {
if (start) {
return;
}
mAlreadyStart = false;
Glide.with(Context.getApplicationContext()).pauseRequests();
} else {
if (!start) {
return;
}
mAlreadyStart = true;
Glide.with(Context.getApplicationContext()).resumeRequests();
}
}


这里就解决了我项目中的问题,还可以实现在滑动时加载图片不滑动就不加载图片,也可以很好的避免不必要的加载。

有什么问题也可以留言提问哈。欢迎各位看官留言提出意见,谢啦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息