当前位置: 首页 > 知识库问答 >
问题:

IllegalStateException,因为okhttp异步HTTP POST请求中的onResponse代码

羊舌涵涤
2023-03-14

我在这里写了一段代码:

public class Wizard1 extends GuidedStepFragment implements Callback {

    private boolean sendPhoneNumber(String userPhoneNumber) {

        OkHttpClient client = new OkHttpClient();

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("request_magic_code", Urls.REQUEST_MAGIC_CODE)
                .build();

        Request request = new Request.Builder()
                .url(Urls.HOST + Urls.SEND_PHONE_NUMBER)
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(this);
        return success;
    }

    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        e.printStackTrace();
    }

    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
        ResponseBody myResponse = response.body();
        Log.d("SS", response.body().string());

    Log.d("SS", response.body().string());

        if (myResponse != null) {
            success = true;
            }

}

当我运行它时,令人惊讶的是,我得到了java.lang.IllegalStateException。更令人惊讶的是,如果我删除第二个log.d行,异常将不会发生!

发生什么事了?为什么在onResponse中添加虚拟行会导致此错误?

以下是完整的错误日志:

10-24 05:16:38.307 663 9-6659/com.example.android.persistence W/system.err:java.lang.ILLegalStateException:关闭于Okio.realBufferedSource.rangeEquals(realBufferedSource.java:398),关闭于Okio.realBufferedSource.rangeEquals(realBufferedSource.java:392),关闭于Okhttp3.internal.util.bomaWareCharset(util.java:431),关闭于r:
在Android.support.v17.leanback.supportleanbackshowcase.app.wizard.wizardGetPhoneNumber.onRespon(wizardGetPhoneNumber.java:244)在OKHTTP3.realcall$asynccall.execute(realcall.java:141)在OKHTTP3.internal.namedrunnable.run(namedrunnable.java:32)在爪哇:761)

共有1个答案

松锐藻
2023-03-14

您使用response.body().string()两次

来自OKHTTP3文档:响应主体只能使用一次。

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
    ResponseBody body = response.body();
    if(body != null) {
        try {
            //Use it anytime you want
            String responseString = body.string();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
    ResponseBody body = response.body();
    //Warning: this method loads the requested bytes into memory. Most
    // applications should set a modest limit on {@code byteCount}, such as 1 MiB.
    int bufferSize = 1024 * 1024;
    ResponseBody copy = response.peekBody(bufferSize);
}

但是要注意正确使用buffersize,以防止OutOfMemoryError

附言。您不需要将string记录到LogCat。有几种更有效的方法来调试OkHttp客户机,例如

  • https://github.com/itkacher/okHttpProfiler-用于Android studio的插件,用于分析OkHttp请求
  • https://www.charlesproxy.com/-http代理应用程序(安装手册)
  • http://facebook.github.io/stetho/-Android应用程序的调试桥
 类似资料:
  • 对传递的 URL 发出一个 POST 请求。 使用 XMLHttpRequest web api 对给定的url 发出一个 post 请求。 用 setRequestHeader 方法设置 HTTP 请求头的值。 通过调用给定的 callback 和 responseText 来处理 onload 事件。 通过运行提供的 err 函数,处理onerror事件。 省略第三个参数 data ,不发送数

  • 我希望我的请求触发一些长时间运行的操作,这些操作应该在后台执行。我编写了以下实现,应该在后台处理我的操作,但实际上我的请求是同步执行的: 在日志中,我看到以下内容: 我看到我的在另一个线程中执行,但出于某种原因,我的原始请求等待sleep完成 更新1:

  • 问题内容: 我正在用PHP执行两个curl请求。它们的外观如下: 他们正在工作,但有时第二个curl post请求未执行。 我想同时执行这两个请求。 我怎样才能做到这一点?请注意,他们在邮递区中采取不同的选择。 谢谢你的帮助! 问题答案: 因此,您要做的是异步执行cUrl请求。 因此,您将需要一个用于php的异步/并行处理库。 php的著名线程库之一是 您首先需要获取dll / so文件并将其保存

  • 问题内容: 我尝试了python 请求库文档中提供的示例。 使用,我得到了响应代码,但是我想获得所请求的每个页面的内容。例如,这不起作用: 问题答案: 注意 下面的答案是不适用于请求v0.13.0 +。编写此问题后,异步功能已移至。但是,你可以将其替换为下面的内容,它应该可以工作。 我已经留下了这个答案,以反映原始问题,即有关使用请求的问题。 要异步执行多个任务,你必须: 为每个对象定义一个函数(

  • 本文向大家介绍全面解析iOS中同步请求、异步请求、GET请求、POST请求,包括了全面解析iOS中同步请求、异步请求、GET请求、POST请求的使用技巧和注意事项,需要的朋友参考一下 先给大家分别介绍下iOS中同步请求、异步请求、GET请求、POST所代表的意思,然后在逐一通过实例给大家介绍。 1、同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进

  • Spring MVC 3.2开始引入了基于Servlet 3的异步请求处理。相比以前,控制器方法已经不一定需要返回一个值,而是可以返回一个java.util.concurrent.Callable的对象,并通过Spring MVC所管理的线程来产生返回值。与此同时,Servlet容器的主线程则可以退出并释放其资源了,同时也允许容器去处理其他的请求。通过一个TaskExecutor,Spring M