记录一次gilde引起的异常:(java.lang.IllegalStateException: Cannot pool recycled bitmap)

本文深入探讨了Glide在Android应用中加载图片时出现的java.lang.IllegalStateException异常,详细分析了异常产生的原因,涉及bitmap回收问题,并提供了解决方案,推荐使用OkHttp替代Glide进行图片加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 遇到的log日志打印如下:

12-15 16:55:50.435 20360-20360/com.ysb E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ysb, PID: 20360
    java.lang.RuntimeException: Unable to destroy activity {com.xxx/com.xxx.ui.xxx.xxxActivity}: java.lang.IllegalStateException: Cannot pool recycled bitmap
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4711)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4729)
        at android.app.ActivityThread.-wrap7(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1709)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:6727)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
     Caused by: java.lang.IllegalStateException: Cannot pool recycled bitmap
        at com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool.put(LruBitmapPool.java:88)
        at com.bumptech.glide.load.resource.bitmap.BitmapResource.recycle(BitmapResource.java:60)
        at com.bumptech.glide.load.engine.EngineResource.recycle(EngineResource.java:73)
        at com.bumptech.glide.load.engine.ResourceRecycler.recycle(ResourceRecycler.java:28)
        at com.bumptech.glide.load.engine.Engine.onResourceReleased(Engine.java:329)
        at com.bumptech.glide.load.engine.EngineResource.release(EngineResource.java:112)
        at com.bumptech.glide.load.engine.Engine.release(Engine.java:287)
        at com.bumptech.glide.request.SingleRequest.releaseResource(SingleRequest.java:326)
        at com.bumptech.glide.request.SingleRequest.clear(SingleRequest.java:316)
        at com.bumptech.glide.manager.RequestTracker.clearRemoveAndMaybeRecycle(RequestTracker.java:79)
        at com.bumptech.glide.manager.RequestTracker.clearRemoveAndRecycle(RequestTracker.java:66)
        at com.bumptech.glide.RequestManager.untrack(RequestManager.java:603)
        at com.bumptech.glide.RequestManager.untrackOrDelegate(RequestManager.java:571)
        at com.bumptech.glide.RequestManager.clear(RequestManager.java:559)
        at com.bumptech.glide.RequestManager.onDestroy(RequestManager.java:303)
        at com.bumptech.glide.manager.ActivityFragmentLifecycle.onDestroy(ActivityFragmentLifecycle.java:65)
        at com.bumptech.glide.manager.RequestManagerFragment.onDestroy(RequestManagerFragment.java:213)
        at android.app.Fragment.performDestroy(Fragment.java:2587)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1153)
        at android.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:2079)
        at android.app.FragmentController.dispatchDestroy(FragmentController.java:242)
        at android.app.Activity.performDestroy(Activity.java:6975)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1228)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4698)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4729) 
        at android.app.ActivityThread.-wrap7(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1709) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:176) 
        at android.app.ActivityThread.main(ActivityThread.java:6727) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794) 

找了差不多两天,终于解决。

  • java.lang.IllegalStateException异常产生的原因及解决办法  

该异常表示,当前对客户端的响应已经结束,不能在响应已经结束(或说消亡)后再向客户端(实际上是缓冲区)输出任何内容。

  • 具体分析:

                        首先解释下flush(),我们知道在使用读写流的时候数据先被读入内存这个缓冲区中,

                         然后再写入文件,但是当数据读完时不代表数据已经写入文件完毕,因为可能还有

                         一部分仍未写入文件而留在内存中,这时调用flush()方法就会把缓冲区的数据强行

                         清空输出,因此flush()的作用就是保证缓存清空输出。

                        response是服务端对客户端请求的一个响应,其中封装了响应头、状态码、内容等,

                        服务端在把response提交到客户端之前,会向缓冲区内写入响应头和状态码,然后

                        将所有内容flush。这就标志着该次响应已经committed(提交)。对于当前页面中

                        已经committed(提交)的response,就不能再使用这个response向缓冲区写任何东西

                     (注:同一个页面中的response.XXX()是同一个response的不同方法,只要其中一个

                        已经导致了committed,那么其它类似方式的调用都会导致 IllegalStateException异常)。

  • 【注意】能够导致响应已经committed的操作包括:forward, redirect, flushBuffer。
  • 由此可知:

是因为缓存的时候图片过大,而加载的图片无法回收。(具体原因是由于Glide内部优化问题引起的。)

Glide中具体Issues如下:

https://github.com/bumptech/glide/issues/2012(未解决)

 

  • 解决方案:

换用其他方法获取到bitmap来进行操作。

具体代码如下:

OkHttpClient okHttpClient = new OkHttpClient();
                Request request = new Request.Builder()
                        .url(Variable.headPicAccessaddress + intoExhibitionAdapter.getItem(imagePosition).getUrl())
                        .build();
                okHttpClient.newCall(request).enqueue(new Callback() {
                    public void onFailure(Call call, IOException e) {

                    }
                    public void onResponse(Call call, Response response) throws IOException {
                        InputStream inputStream = response.body().byteStream();//得到图片的流
                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                        EventBus.getDefault().post(new MessageEvent(bitmap));
                    }
                });

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值