0
点赞
收藏
分享

微信扫一扫

鸿蒙应用开发-使用OkHttp提示java.lang.IllegalStateException: closed问题

闲鱼不咸_99f1 2022-03-19 阅读 34
java鸿蒙

在鸿蒙应用开发中使用OkHttp的时候出现了一个匪夷所思的Bug,错误提醒如下:

Device info:JAD-AL50
Build info:JAD-AL50 2.0.0.241(C00E230R3P4)
Module name:com.example.attendenceapplication
Version:1.0.0
Pid:4504
Uid:1011557
Foreground:Yes
Reason:IllegalStateException
Selected stacktrace:
java.lang.IllegalStateException: closed
	at okio.RealBufferedSource.select(RealBufferedSource.java:93)
	at okhttp3.internal.Util.bomAwareCharset(Util.java:467)
	at okhttp3.ResponseBody.string(ResponseBody.java:181)
	at com.example.attendenceapplication.slice.TakePhotoSlice$2.onResponse(TakePhotoSlice.java:224)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.lang.Thread.run(Thread.java:929)

根据错误提醒可知Bug发生在代码的224行,如下:

    @Override
                public void onResponse(Call call, Response response) throws IOException {
                    System.out.println("body is " +response.body().string());
                    ResultVO resultVO = gson.fromJson(response.body().string(),ResultVO.class);//224行代码
                    System.out.println(resultVO.getCode());
                    System.out.println(resultVO.getMsg());
                    uiTaskDispatcher.asyncDispatch(() -> {
                        showTips(TakePhotoSlice.this, resultVO.getMsg());
                        //如果人脸上传成功则退出拍照界面
                        if (resultVO.getMsg().trim().equals("人脸上传成功")){
                            terminateAbility();
                        }
                    });

                }
            });

onResponse是OkHttp的一个回调函数,其中Response response可以获取后端返回的数据包括headers、body等。第224行代码是将Response的body转换为对应的实体类,正是这一行代码导致了Bug的出现。根据错误提醒可知我应该是使用了一个已经关闭的数据流,但是我并没有关闭数据流啊,怎么回事。
经过一天一夜的折腾,我才知道为什么会报错了。
因为在 System.out.println("body is " +response.body().string());这一行代码中执行了response.body().string()方法,此方法不仅会把response的body转换为字符串,同时还会把数据流进行关闭,导致ResultVO resultVO = gson.fromJson(response.body().string(),ResultVO.class);转换不了实体类,简而言之就是使用了两次response.body().string()。
string()方法的源码如下:从源码可以看出在执行string()方法后就会执行 $closeResource(var2, source);方法,从而关闭了数据流。

解决办法就是将System.out.println("body is " +response.body().string());注释掉即可

public final String string() throws IOException {
    BufferedSource source = this.source();
    Throwable var2 = null;

    String var4;
    try {
        Charset charset = Util.bomAwareCharset(source, this.charset());
        var4 = source.readString(charset);
    } catch (Throwable var8) {
        var2 = var8;
        throw var8;
    } finally {
        if (source != null) {
            $closeResource(var2, source);
        }

    }

    return var4;
}
举报

相关推荐

0 条评论