Подтвердить что ты не робот

Дооснащение и OkHttpClient, тайм-аут соединения catch в методе сбоя

У меня есть следующая настройка:

final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(5, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(5, TimeUnit.SECONDS);

RestAdapter.Builder builder = new RestAdapter.Builder()
        .setEndpoint(ROOT)
        .setClient(new OkClient(okHttpClient))
        .setLogLevel(RestAdapter.LogLevel.FULL);

Я пытаюсь обработать ситуацию, когда мой сервер отключен, и пользователь получает исключение таймаута соединения, это мой журнал:

java.net.SocketTimeoutException: failed to connect to /192.168.0.53 (port 3000) after 5000ms

Полная регистрация: http://pastebin.com/gscCGb7x

Есть ли способ перенаправить это на метод отказоустойчивости, чтобы я мог справиться с этим там?

Спасибо заранее!

4b9b3361

Ответ 1

Для дооснащения 2

Определите слушателя в вашем экземпляре веб-службы:

public interface OnConnectionTimeoutListener {
    void onConnectionTimeout();
}

Добавьте перехватчик в ваш веб-сервис:

public WebServiceClient() {
    OkHttpClient client = new OkHttpClient();
    client.setConnectTimeout(10, TimeUnit.SECONDS);
    client.setReadTimeout(30, TimeUnit.SECONDS);
    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            return onOnIntercept(chain);
        }
    });
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
    webService = retrofit.create(WebService.class);
}

Приложите код перехвата к блоку try-catch и уведомите слушателя, когда произойдет исключение:

private Response onOnIntercept(Chain chain) throws IOException {
    try {
        Response response = chain.proceed(chain.request());
        String content = UtilityMethods.convertResponseToString(response);
        Log.d(TAG, lastCalledMethodName + " - " + content);
        return response.newBuilder().body(ResponseBody.create(response.body().contentType(), content)).build();
    }
    catch (SocketTimeoutException exception) {
        exception.printStackTrace();
        if(listener != null)
            listener.onConnectionTimeout();
    }

    return chain.proceed(chain.request());
}

Котлин

Если вы хотите использовать Retrofit в Kotlin выполните следующие действия:

Определите ваш интерфейс Retrofit:

interface GitHubApi {

    @GET("/users/{userName}/repos")
    fun repos(@Path("userName") userName: String): Call<List<Repo>>
}

Реализуйте свой сервис:

class Api(...) {

    private val baseUrl = "https://api.github.com"
    private val api: GitHubApi

    private fun loggingInterceptor(...): HttpLoggingInterceptor {...}

    private fun okHttpBuilder(): OkHttpClient {...}

    init {...}

    fun repos(
        userName: String,
        onSuccess: (list: List<Repo>?) -> Unit,
        onFailure: (message: String?) -> Unit): Future<Unit> {
        return runAsync(api.repos(userName), onSuccess, onFailure)
    }

    private fun <T> runAsync(
        call: retrofit2.Call<T>,
        onSuccess: (T?) -> Unit,
        onFailure: (message: String?) -> Unit) : Future<Unit> {
        return doAsync {
            try {
                val response = call.execute()
                when {
                    response.isSuccessful -> response.body()?.let {
                        onSuccess(it)
                    }
                    else -> {
                        onFailure(response.raw().message())
                    }
                }
            } catch (e: IOException) {
                if (e is SocketTimeoutException) {
                    onFailure("Response time out!")
                } else {
                    onFailure(e.message)
                }
            }
        }
    }
}

Позвоните в службу, где вы хотите:

Api().repos("olcayertas",
    onSuccess = {
        Log.d("MainActivity", "Response:\n" + toJson(it))
    },
    onFailure = {
        Log.e("MainActivity", "Error: $it")
    })

Вы можете обработать любое исключение в функции runAsync.

Вы можете получить полностью рабочий пример здесь.

Ответ 2

 @Override
    public void onFailure(Call call, Throwable t) {
        if(t instanceof SocketTimeoutException){
            message = "Socket Time out. Please try again.";
        }
    }

Ответ 3

По-видимому, исключение превращается в исключение RetrofitException, поэтому вы можете обрабатывать его в методе сбоя.

Ответ 4

Это немного сложнее. С помощью "Дооснащения" вы можете совершать вызовы API, которые либо синхронны, либо асинхронны.

Если ваша конечная точка возвращает void и имеет обратный вызов, она является асинхронной. Если он что-то возвращает и не имеет обратного вызова, он синхронно.

Для асинхронных вызовов вы получаете это исключение в методе onFailure(...) вашего обратного вызова.

Для синхронных вызовов вы не получите его вообще, если только вы не завершите свой вызов в try/catch.

try {
   // your synchronous call goes here  
} catch (RetrofitError error) {
   // handle errors
}

Обновление: вышеприведенный ответ применяется к Retrofit 1.9. Retrofit 2.0 сильно изменил это. Если вам интересно, как теперь работает Retrofit 2.0, в этой статье приведены некоторые указатели http://inthecheesefactory.com/blog/retrofit-2.0/en

Ответ 5

= > Используйте следующие типы кода, которые он работал у меня...

//Создаем объект OkHttpClient

OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(100, TimeUnit.SECONDS)
        .readTimeout(100,TimeUnit.SECONDS).build();

//и установите объект OkHttpClient в вашей модификации

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("yourbaseurl").client(client)
        .addConverterFactory(GsonConverterFactory.create(new  Gson())).build();

Ответ 6

Я думаю, что это не предпочтительный способ, но вы можете сделать это следующим образом:

override fun onFailure(call: Call<ResponseResult>, t: Throwable) {
                if (t is TimeoutException) {
                    MyToast.displayToast(context, "Connection timed out!!")
                } 
}