【问题标题】:java.net.SocketTimeoutException in okhttpokhttp 中的 java.net.SocketTimeoutException
【发布时间】:2017-03-03 09:53:24
【问题描述】:

这里从json 获取数据需要很长时间。删除并重新安装后,它将在 1 分钟内获得 json,当我再次单击 json 的按钮时,它需要很长时间,但仍然没有数据进入 listview

这是我的异常代码

E/JSONDemo: IOExceptiojava.net.SocketTimeoutException
  at java.net.PlainSocketImpl.read(PlainSocketImpl.java:493)
  at java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
  at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:242)
  at okio.Okio$2.read(Okio.java:140)
  at okio.AsyncTimeout$2.read(AsyncTimeout.java:238)
  at okio.RealBufferedSource.indexOf(RealBufferedSource.java:325)
  at okio.RealBufferedSource.indexOf(RealBufferedSource.java:314)
  at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:210)
  at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:184)
  at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:125)
  at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:775)
  at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:86)
  at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:760)
  at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:613)
  at okhttp3.RealCall.getResponse(RealCall.java:244)
  at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
  at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
  at okhttp3.RealCall.access$100(RealCall.java:30)
  at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
  at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
  at java.lang.Thread.run(Thread.java:818)

这是java文件中的json代码:

progress = ProgressDialog.show(MainActivity.this, "dialog title", "dialog message", true);
Toast.makeText(MainActivity.this, "ok", Toast.LENGTH_LONG).show();

    if (isNetworkAvailable()) {

        String url = "ConstantValue.URL";
        RequestBody formBody = new FormBody.Builder()
                .add(employeeId, value)
                .build();

        try {
            post(url, formBody, new Callback() {

                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e("JSONDemo", "IOException", e);
                }

                @Override
                public void onResponse(final Call call, final Response response) throws IOException {
                    String JSON = response.body().string();
                     Log.e("res", " " + JSON);
                     try {
                         JSONObject jsonObj = new JSONObject(JSON);
                         JSONArray resultarr = jsonObj.getJSONArray("result");
                         final JSONArray resultarr1 = jsonObj.getJSONArray("result1");

                         if (resultarr1.length() == 0) {
                             showAlertDialog("API", "Data Unavailable");
                         } else {

                             for (int i = 0; i < resultarr1.length(); i++) {

                                 Employee emp = new Employee();
                                 JSONObject result1obj = resultarr1.getJSONObject(i);
                                 String result1Id = result1obj.getString("ID");
                                 String result1Name = result1obj.getString("NAME");
                                 String result1Value = result1obj.getString("VALUE");
                                 Log.e("result", " " + result1Name);
                                 Log.e("result", " " + result1Value);
                                 Log.e("result", " " + result1Id);
                                 emp.setValue(result1Value);
                                 emp.setName(result1Name);
                                 emp.setId(result1Id);

                                 arr.add(emp);

                             }
                         }

                         runOnUiThread(new Runnable() {
                             @Override
                             public void run() {

                                 // you can access all the UI componenet
                                 if (progress.isShowing()) 
                                     progress.dismiss();
                                 cu.notifyDataSetChanged();
                             }
                         });
                     } catch (Exception e) {
                         Log.e("JSONDemo", "onResponse", e);
                         showAlertDialog("API","Something went wrong");
                     }

                 }
             });

         } catch (Exception e) {
             Log.e("JSONDemo", "Post Exception", e);
         }

     } else {
         Toast.makeText(MainActivity.this, "Internet not available", Toast.LENGTH_LONG).show();
     }
}

其他代码:

private final OkHttpClient client = new OkHttpClient();


Call post(String url, RequestBody formBody, Callback callback) throws IOException {

    Request request = new Request.Builder()
            .url(url)
            .post(formBody)
            .build();

    client.setConnectTimeout(30, TimeUnit.SECONDS);
    client.setReadTimeout(30, TimeUnit.SECONDS);
    client.setWriteTimeout(30, TimeUnit.SECONDS);

    Call call = client.newCall(request);
    call.enqueue(callback);
    return call;
}

【问题讨论】:

    标签: android json okhttp socketexception okhttp3


    【解决方案1】:

    IOException java.net.SocketTimeoutException 发生在以下情况:

    1. 服务器很慢,默认超时时间更短。所以只需根据你的时间设置超时值。
    2. 服务器工作正常,但超时值较短。所以更改超时值,如下面的代码 sn-p。
    OkHttpClient client = new OkHttpClient();
    
    client.setConnectTimeout(30, TimeUnit.SECONDS);
    client.setReadTimeout(30, TimeUnit.SECONDS);
    client.setWriteTimeout(30, TimeUnit.SECONDS);
    

    如果您使用的是 OkHttp 3,那么您必须使用构建器来完成。

    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.connectTimeout(30, TimeUnit.SECONDS); 
    builder.readTimeout(30, TimeUnit.SECONDS); 
    builder.writeTimeout(30, TimeUnit.SECONDS); 
    client = builder.build();
    

    【讨论】:

    • 我已经编辑了,但在这里我没有得到 client.setConnectTimeout(30, TimeUnit.SECONDS);client.setReadTimeout(30, TimeUnit.SECONDS);client.setWriteTimeout(30, TimeUnit.SECONDS);
    • @Abhi 如果您使用的是 okhttp3,那么您必须使用构建器进行操作。 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(30, TimeUnit.SECONDS); builder.readTimeout(30, TimeUnit.SECONDS); builder.writeTimeout(30, TimeUnit.SECONDS);客户端 = builder.build();
    • @Cognoscis 我认为您应该使用该信息/代码提交答案。
    • 这样做有错吗? OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build();
    • 这个答案将设置更多超时但不能修复崩溃,您应该处理发生的异常并使用重试按钮通知 UI
    【解决方案2】:

    仅添加此内容并不能解决您的问题:

    OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
    

    如果您使用 Kotlin + Retrofit + Coroutines,那么只需使用 trycatch 进行网络操作,例如,

    viewModelScope.launch(Dispatchers.IO) {
            try {
                val userListResponseModel = apiEndPointsInterface.usersList()
                returnusersList(userListResponseModel)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    

    其中,Exception 是 kotlin 的类型,而不是 java.lang 的类型

    这将处理每个异常,例如,

    1. HttpException
    2. SocketTimeoutException
    3. 致命异常:DefaultDispatcher 等

    这是我的usersList() 函数

    @GET(AppConstants.APIEndPoints.HOME_CONTENT)
    suspend fun usersList(): UserListResponseModel
    

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2019-12-16
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多