Як встановити час очікування в бібліотеці ретрофітів?


180

Я використовую бібліотеку Retrofit у своєму додатку, і я хотів би встановити час очікування в 60 секунд. Чи має Retrofit якийсь спосіб зробити це?

Я встановив модернізацію таким чином:

RestAdapter restAdapter = new RestAdapter.Builder()
    .setServer(BuildConfig.BASE_URL)
    .setConverter(new GsonConverter(gson))
    .build();

Як встановити час очікування?

Відповіді:


320

Ви можете встановити тайм-аути на базовому клієнті HTTP. Якщо ви не вказали клієнта, Retrofit створить його із затримкою підключення та зчитування за замовчуванням. Щоб встановити власні тайм-аути, вам потрібно налаштувати власного клієнта та подати його на RestAdapter.Builder.

Варіант - використовувати клієнт OkHttp , також від Square.

1. Додайте залежність бібліотеки

У build.gradle включіть цей рядок:

compile 'com.squareup.okhttp:okhttp:x.x.x'

Де x.x.xпотрібна версія бібліотеки.

2. Встановіть клієнта

Наприклад, якщо ви хочете встановити тайм-аут в 60 секунд, зробіть цей спосіб для Retrofit перед версією 2 та Okhttp перед версією 3 ( ДЛЯ НОВИХ ВЕРСІЙ, ДИВІТЬ ВИДАЛЕННЯ ):

public RestAdapter providesRestAdapter(Gson gson) {
    final OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
    okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);

    return new RestAdapter.Builder()
        .setEndpoint(BuildConfig.BASE_URL)
        .setConverter(new GsonConverter(gson))
        .setClient(new OkClient(okHttpClient))
        .build();
}

ЗРІД 1

Для okhttp версій, оскільки 3.x.xви повинні встановити залежність таким чином:

compile 'com.squareup.okhttp3:okhttp:x.x.x'

І встановіть клієнта, використовуючи шаблон конструктора:

final OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(60, TimeUnit.SECONDS)
        .connectTimeout(60, TimeUnit.SECONDS)
        .build();

Більше інформації в Timeouts


EDIT 2

Версії для вдосконалення 2.x.xтакож використовують схему конструктора, тому змініть блок повернення вище на це:

return new Retrofit.Builder()
    .baseUrl(BuildConfig.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(okHttpClient)
    .build();

Якщо ви використовуєте такий код, як мій providesRestAdapterметод, то змініть тип повернення методу на Retrofit .

Більше інформації в Retrofit 2 - Посібник з оновлення від 1.9


ps: Якщо ваш minSdkVersion більше 8, ви можете використовувати TimeUnit.MINUTES:

okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);

Детальніше про пристрої див. У TimeUnit .


Я не бачу setReadTimeout в новій версії okhttp, будь-яких нових способів зробити це?
Lion789

1
Я використовую okhttp3, і для мене я використав цей код: new okhttp3.OkHttpClient (). NewBuilder (); okHttpClient.readTimeout (60, TimeUnit.SECONDS); okHttpClient.writeTimeout (60, TimeUnit.SECONDS); okHttpClient.connectTimeout (60, TimeUnit.SECONDS); новий Retrofit.Builder () .client (okHttpClient.build ())
lucasddaniel

@lucasddaniel Ви можете скористатись відредагованою відповіддю та розмістити заявлене ім'я OkHttpClient у своєму конструкторі ретрофітів, як-от "Retrofit retrofitBuilderName = new Retrofit.Builder (). клієнт (okttpclientName). build (); '
f123

1
@Solace У мене є thid метод: public Gson providesGson() { return new GsonBuilder().create(); }. Так що я роблю це: Gson gson = module.providesGson(); RestAdapter adapter = module.providesRestAdapter(gson);. Де модуль - це екземпляр належного класу, у якому є всі ці методи
androidevil

1
Якщо ви використовуєте OkHttp3, вам доведеться використовувати compile 'com.squareup.okhttp3:okhttp:3.x.x'імпорт градусів, як у відповіді нижче від Teo
NineToeNerd

82

Ці відповіді для мене застаріли, тож ось як це вийшло.

Додати OkHttp, у моєму випадку версія така 3.3.1:

compile 'com.squareup.okhttp3:okhttp:3.3.1'

Потім перед тим, як створити модернізацію, зробіть це:

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .readTimeout(60, TimeUnit.SECONDS)
    .writeTimeout(60, TimeUnit.SECONDS)
    .build();
return new Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

мені погано, я пропустив ()
Джонатан Асте

що буде після цього 60 секунд? Чи можемо ми показати будь-яке підказку саме там?
Арнольд Браун

@ArnoldBrown Вам не вдасться здійснити виклик, який зателефонував на Faailure ()
C. Skjerdal

10
public class ApiClient {
    private static Retrofit retrofit = null;
    private static final Object LOCK = new Object();

    public static void clear() {
        synchronized (LOCK) {
            retrofit = null;
        }
    }

    public static Retrofit getClient() {
        synchronized (LOCK) {
            if (retrofit == null) {

                Gson gson = new GsonBuilder()
                        .setLenient()
                        .create();

                OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                        .connectTimeout(40, TimeUnit.SECONDS)
                        .readTimeout(60, TimeUnit.SECONDS)
                        .writeTimeout(60, TimeUnit.SECONDS)
                        .build();


                retrofit = new Retrofit.Builder()
                        .client(okHttpClient)
                        .baseUrl(Constants.WEB_SERVICE)
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .build();
            }
            return retrofit;
        }

    }

    public static RequestBody plain(String content) {
        return getRequestBody("text/plain", content);
    }

    public static RequestBody getRequestBody(String type, String content) {
        return RequestBody.create(MediaType.parse(type), content);
    }
}

@FormUrlEncoded
@POST("architect/project_list_Design_files")
Call<DesignListModel> getProjectDesign(
        @Field("project_id") String project_id);


@Multipart
@POST("architect/upload_design")
Call<BoqListModel> getUpLoadDesign(
        @Part("user_id") RequestBody user_id,
        @Part("request_id") RequestBody request_id,
        @Part List<MultipartBody.Part> image_file,
        @Part List<MultipartBody.Part> design_upload_doc);


private void getMyProjectList()
{

    ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
    Call<MyProjectListModel> call = apiService.getMyProjectList("",Sorting,latitude,longitude,Search,Offset+"",Limit);
    call.enqueue(new Callback<MyProjectListModel>() {
        @Override
        public void onResponse(Call<MyProjectListModel> call, Response<MyProjectListModel> response) {
            try {
                Log.e("response",response.body()+"");

            } catch (Exception e)
            {
                Log.e("onResponse: ", e.toString());
                           }
        }
        @Override
        public void onFailure(Call<MyProjectListModel> call, Throwable t)
        {
            Log.e( "onFailure: ",t.toString());
                   }
    });
}

// file upload

private void getUpload(String path,String id)
    {

        ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
        MultipartBody.Part GalleryImage = null;
        if (path!="")
        {
            File file = new File(path);
            RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            GalleryImage = MultipartBody.Part.createFormData("image", file.getName(), reqFile);
        }

        RequestBody UserId = RequestBody.create(MediaType.parse("text/plain"), id);
        Call<uplod_file> call = apiService.geUplodFileCall(UserId,GalleryImage);
        call.enqueue(new Callback<uplod_file>() {
            @Override
            public void onResponse(Call<uplod_file> call, Response<uplod_file> response) {
                try {
                    Log.e("response",response.body()+"");
                    Toast.makeText(getApplicationContext(),response.body().getMessage(),Toast.LENGTH_SHORT).show();

                } catch (Exception e)
                {
                    Log.e("onResponse: ", e.toString());
                }
            }
            @Override
            public void onFailure(Call<uplod_file> call, Throwable t)
            {
                Log.e( "onFailure: ",t.toString());
            }
        });
    }

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

4
Будь ласка, розширення вашої відповіді.
humble_wolf

1

Я використовую Retrofit 1.9 для отримання XML .

public class ServicioConexionRetrofitXML {

    public static final String API_BASE_URL = new GestorPreferencias().getPreferencias().getHost();
    public static final long tiempoMaximoRespuestaSegundos = 60;
    public static final long tiempoMaximoLecturaSegundos = 100;
    public static final OkHttpClient clienteOkHttp = new OkHttpClient();


    private static RestAdapter.Builder builder = new RestAdapter.Builder().
            setEndpoint(API_BASE_URL).
            setClient(new OkClient(clienteOkHttp)).setConverter(new SimpleXMLConverter());


    public static <S> S createService(Class<S> serviceClass) {
        clienteOkHttp.setConnectTimeout(tiempoMaximoRespuestaSegundos, TimeUnit.SECONDS);
        clienteOkHttp.setReadTimeout(tiempoMaximoLecturaSegundos, TimeUnit.SECONDS);
        RestAdapter adapter = builder.build();
        return adapter.create(serviceClass);
    }

}

Якщо ви використовуєте Retrofit 1.9.0 та okhttp 2.6.0, додайте до файлу Gradle.

    compile 'com.squareup.retrofit:retrofit:1.9.0'
    compile 'com.squareup.okhttp:okhttp:2.6.0'
    // Librería de retrofit para XML converter (Simple) Se excluyen grupos para que no entre
    // en conflicto.
    compile('com.squareup.retrofit:converter-simplexml:1.9.0') {
        exclude group: 'xpp3', module: 'xpp3'
        exclude group: 'stax', module: 'stax-api'
        exclude group: 'stax', module: 'stax'
    }

Примітка. Якщо вам потрібно отримати JSON , просто видаліть з коду вище.

.setConverter(new SimpleXMLConverter())

1

Для Retrofit1.9 для користувачів OkHttp3 ось рішення,

.setClient(new Ok3Client(new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build()))

0
public class ApiModule {
    public WebService apiService(Context context) {
        String mBaseUrl = context.getString(BuildConfig.DEBUG ? R.string.local_url : R.string.live_url);

        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .connectTimeout(120, TimeUnit.SECONDS)
                .addInterceptor(loggingInterceptor)
                //.addNetworkInterceptor(networkInterceptor)
                .build();

        return new Retrofit.Builder().baseUrl(mBaseUrl)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build().create(WebService.class);

    }
}

0

Це буде найкращий спосіб встановити тайм-аут для кожної послуги (проходження тайм-ауту як параметр)

public static Retrofit getClient(String baseUrl, int serviceTimeout) {
        Retrofit retrofitselected = baseUrl.contains("http:") ? retrofit : retrofithttps;
        if (retrofitselected == null || retrofitselected.equals(retrofithttps)) {
            retrofitselected = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create(getGson().create()))
                    .client(!BuildConfig.FLAVOR.equals("PRE") ? new OkHttpClient.Builder()
                            .addInterceptor(new ResponseInterceptor())
                            .connectTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                            .writeTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                            .readTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                            .build() : getUnsafeOkHttpClient(serviceTimeout))
                    .build();
        }
        return retrofitselected;
    }

І не пропустіть це для OkHttpClient.

private static OkHttpClient getUnsafeOkHttpClient(int serviceTimeout) {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder
                    .addInterceptor(new ResponseInterceptor())
                    .connectTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                    .writeTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                    .readTimeout(serviceTimeout, TimeUnit.MILLISECONDS)
                    .build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Сподіваюся, що це допоможе комусь.


0

Я знайшов цей приклад

https://github.com/square/retrofit/isissue/1557

Тут ми встановлюємо користувальницький клієнт підключення до клієнта перед тим, як створити реалізацію служби відпочинку API.

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import retrofit.Endpoint
import retrofit.RestAdapter
import retrofit.client.Request
import retrofit.client.UrlConnectionClient
import retrofit.converter.GsonConverter


class ClientBuilder {

    public static <T> T buildClient(final Class<T> client, final String serviceUrl) {
        Endpoint mCustomRetrofitEndpoint = new CustomRetrofitEndpoint()


        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
        RestAdapter.Builder builder = new RestAdapter.Builder()
            .setEndpoint(mCustomRetrofitEndpoint)
            .setConverter(new GsonConverter(gson))
            .setClient(new MyUrlConnectionClient())
        RestAdapter restAdapter = builder.build()
        return restAdapter.create(client)
    }
}

 public final class MyUrlConnectionClient extends UrlConnectionClient {
        @Override
        protected HttpURLConnection openConnection(Request request) {
            HttpURLConnection connection = super.openConnection(request);
            connection.setConnectTimeout(15 * 1000);
            connection.setReadTimeout(30 * 1000);
            return connection;
        }
    }

-1
public class ApiClient {
    private static Retrofit retrofit = null;
    private static final Object LOCK = new Object();

    public static void clear() {
        synchronized (LOCK) {
            retrofit = null;
        }
    }

    public static Retrofit getClient() {
        synchronized (LOCK) {
            if (retrofit == null) {

                Gson gson = new GsonBuilder()
                        .setLenient()
                        .create();

                OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                        .connectTimeout(40, TimeUnit.SECONDS)
                        .readTimeout(60, TimeUnit.SECONDS)
                        .writeTimeout(60, TimeUnit.SECONDS)
                        .build();

                // Log.e("jjj", "=" + (MySharedPreference.getmInstance().isEnglish() ? Constant.WEB_SERVICE : Constant.WEB_SERVICE_ARABIC));
                retrofit = new Retrofit.Builder()
                        .client(okHttpClient)
                        .baseUrl(Constants.WEB_SERVICE)
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .build();
            }
            return retrofit;
        }`enter code here`

    }

    public static RequestBody plain(String content) {
        return getRequestBody("text/plain", content);
    }

    public static RequestBody getRequestBody(String type, String content) {
        return RequestBody.create(MediaType.parse(type), content);
    }
}


-------------------------------------------------------------------------


    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

2
Хоча цей фрагмент коду може вирішити питання, зокрема пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. Будь ласка, намагайтеся не переповнювати свій код пояснювальними коментарями, це зменшує читабельність і коду, і пояснень!
Фільнор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.