SocketTimeoutException в модернизации
Я пытаюсь отправить запрос на сервер для получения данных, но иногда это происходит SocketTimeoutException
!
я использовал Ok3Client
чтобы решить это, но я столкнулся с тем же исключением, как я могу решить это?
Мой код ниже
public void getNormalLogin() {
if (mProgressDialog == null) {
mProgressDialog = ViewUtils.createProgressDialog(mActivity);
mProgressDialog.show();
} else {
mProgressDialog.show();
}
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
restadapter = new RestAdapter.Builder().setEndpoint(HOST).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new Ok3Client(new OkHttpClient())).build();
mApi = restadapter.create(Api.class);
mApi.SignIn(etEmail.getText().toString(), etPassword.getText().toString(), new Callback<ArrayList<SignUpMainBean>>() {
@Override
public void success(ArrayList<SignUpMainBean> signUpMainBeen, Response response) {
mProgressDialog.dismiss();
LOGD("Status:: ::", String.valueOf(response.getStatus()));
LOGD("Code:: ::", String.valueOf(signUpMainBeen.get(0).getCode()));
if (signUpMainBeen != null && signUpMainBeen.size() > 0) {
if (signUpMainBeen.get(0).getCode() == 1) {
for (int i = 0; i < signUpMainBeen.size(); i++) {
for (int j = 0; j < signUpMainBeen.get(i).getResult().size(); j++) {
showToast(mActivity, getString(R.string.you_have_successfully_login), Toast.LENGTH_SHORT);
LOGD("Success", "Success");
finish();
SignIn.mActivity.finish();
}
}
} else if (signUpMainBeen.get(0).getCode() == 0) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.invalid_email_password), Toast.LENGTH_SHORT);
LOGD("Invalid email or password", "Invalid email or password");
} else if (signUpMainBeen.get(0).getCode() == -1) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.your_account_is_inactive), Toast.LENGTH_SHORT);
LOGD("Your account is inactive", "Your account is inactive");
}
}
}
@Override
public void failure(RetrofitError error) {
mProgressDialog.dismiss();
showToast(mActivity, getString(R.string.can_not_connect_to_server), Toast.LENGTH_SHORT);
LOGD("Failure", "Failure");
}
});
}
}
Мой журнал ошибок
D/Retrofit: java.net.SocketTimeoutException
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:532)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:40)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:255)
at okio.Okio$2.read(Okio.java:139)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at okhttp3.internal.http.Http1xStream.readResponse(Http1xStream.java:185)
at okhttp3.internal.http.Http1xStream.readResponseHeaders(Http1xStream.java:126)
at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)
at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
at okhttp3.RealCall.getResponse(RealCall.java:241)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
at okhttp3.RealCall.execute(RealCall.java:57)
at com.jakewharton.retrofit.Ok3Client.execute(Ok3Client.java:40)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:818)
6 ответов
Увеличьте время, если загрузка занимает больше времени, используйте этот код, который работал для меня
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100,TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("yourbaseurl").client(client)
.addConverterFactory(GsonConverterFactory.create(new Gson())).build();
Предотвращение SocketTimeoutException
вне нашего предела... Один из способов эффективно справиться с этим - определить connection timeout
Пример для
дооснащение 1.9.0
restadapter = new RestAdapter.Builder().setEndpoint(HOST).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new OkHttpClient()
.setReadTimeout(30, TimeUnit.SECONDS)
.setConnectTimeout(30, TimeUnit.SECONDS)).build();
модернизация 2.0.0
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setReadTimeout(30, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
дооснащение 2.4.0
// setting custom timeouts
OkHttpClient.Builder client = new Builder();
client.connectTimeout(15, TimeUnit.SECONDS);
client.readTimeout(15, TimeUnit.SECONDS);
client.writeTimeout(15, TimeUnit.SECONDS);
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
}
return retrofit;
}
Я столкнулся с той же проблемой с некоторым запросом. Обычно получается, когда есть активный запрос и получилSocketTimeoutException
из-за отключения от сети. После этого тот же запрос всегда бросаетSocketTimeoutException
.
Я построил свой OkHttpClient
используя приведенный ниже код, как предложено в "java.net.SocketTimeoutException из HTTP/2-соединения оставляет мертвых клиентов okhttp в пуле":
val builder = OkHttpClient.Builder()
.cache(cache)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.connectionPool(ConnectionPool(0, 5, TimeUnit.MINUTES))
.protocols(listOf(Protocol.HTTP_1_1))
Установка connectionPool
а также protocols
починю SocketTimeoutException
вызвано тайм-аутами.
Это временное исправление, и мы надеемся, что оно будет решено в будущих версиях OkHttp
использован Retrofit
.
val builder = OkHttpClient.Builder()
.cache(cache)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.connectionPool(ConnectionPool(0, 5, TimeUnit.MINUTES))
.protocols(listOf(Protocol.HTTP_1_1))
ConnectionPool(0, 5, TimeUnit.MINUTES) — это код ключа, установите для maxIdleConnections значение 0, чтобы избежать исключения SocketTimeoutException при мультиплексировании. этот случай легко происходит при блокировке/разблокировке экрана.
Мне удается поймать и выбросить новое исключение IOException
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
try {
response = chain.proceed(request);
}catch (SocketTimeoutException e){
throw new IOException();
}
String url = request.url().url().toString();
if (existInWhiteList(url)) {
return response;
}
return logResponse(response);
}
и вы можете добавить свою информацию в это new IOException()
;
Возможное решение для этого - убедиться, что вы отправляете правильное тело запроса на сервер. Например, нужен ли сервер x-www-form-urlencoded
или же form-data
в его теле запроса? Простой способ проверить это с помощью Почтальона.