okhttp中的java.net.SocketTimeoutException

时间:2016-10-21 07:22:18

标签: android json okhttp socketexception okhttp3

这需要花费大量时间从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;
}

2 个答案:

答案 0 :(得分:27)

IOExceptiojava.net.SocketTimeoutException 发生在以下情况。

  1. 服务器速度慢,默认超时时间较短。所以根据你的意思来设置超时值。
  2. 服务器工作正常,但超时值的时间较短。所以改变超时值。如下面的代码片段。
  3. OkHttpClient client = new OkHttpClient();

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

    如果您使用的是okhttp3,则必须使用构建器执行此操作。

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

答案 1 :(得分:1)

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

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            todos: todoData
        }
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(id) {
        this.setState(prevState => {
            const updatedTodos = prevState.todos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return {
                todos: updatedTodos
            }
        })
    }

    render() {
        const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>)

        return (
            <div className="todo-list">
                {todoItems}
            </div>
        )    
    }
}

如果您使用的是 Kotlin + Retrofit + Coroutines ,则只需对网络操作使用function TodoItem(props) { return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} /> <p>{props.item.text}</p> </div> ) } let values = ["VAL1", "VAL2", "VAL3"] let format = "Val 1 -> %1$@ Val 2 -> %2$@ Val 3 -> %3$@" let varArg: CVarArg = // How to convert array to CVarArg? let result = String(format: format, varArg)

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

其中,异常是try而不是catch

这将处理所有类似的异常,

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

这是我的viewModelScope.launch(Dispatchers.IO) { try { val userListResponseModel = apiEndPointsInterface.usersList() returnusersList(userListResponseModel) } catch (e: Exception) { e.printStackTrace() } } 函数

kotlin