Làm cách nào để đặt thời gian chờ trong thư viện Retrofit?


180

Tôi đang sử dụng trang bị thêm thư viện trong ứng dụng của mình và tôi muốn đặt thời gian chờ là 60 giây. Liệu Retrofit có một số cách để làm điều này?

Tôi đặt Retrofit theo cách này:

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

Làm cách nào để đặt thời gian chờ?

Câu trả lời:


320

Bạn có thể đặt thời gian chờ trên máy khách HTTP bên dưới. Nếu bạn không chỉ định ứng dụng khách, Retrofit sẽ tạo một ứng dụng có kết nối và đọc thời gian chờ mặc định. Để đặt thời gian chờ của riêng bạn, bạn cần định cấu hình ứng dụng khách của riêng mình và cung cấp choRestAdapter.Builder .

Một tùy chọn là sử dụng ứng dụng khách OkHttp , cũng từ Square.

1. Thêm phụ thuộc thư viện

Trong build.gradle, bao gồm dòng này:

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

Trong trường hợp x.x.xlà phiên bản thư viện mong muốn.

2. Đặt máy khách

Ví dụ: nếu bạn muốn đặt thời gian chờ là 60 giây, hãy thực hiện theo cách này cho Retrofit trước phiên bản 2 và Okhttp trước phiên bản 3 ( ĐỐI VỚI PHIÊN BẢN MỚI, XEM NHỮNG BÀI VIẾT ):

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();
}

CHỈNH SỬA 1

Đối với các phiên bản okhttp kể từ đó 3.x.x, bạn phải đặt phụ thuộc theo cách này:

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

Và thiết lập ứng dụng khách bằng cách sử dụng mẫu trình xây dựng:

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

Thêm thông tin trong Hết giờ


CHỈNH SỬA 2

Các phiên bản trang bị thêm 2.x.xcũng sử dụng mẫu trình xây dựng, vì vậy hãy thay đổi khối trả về ở trên thành này:

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

Nếu sử dụng một mã như providesRestAdapterphương thức của tôi , thì hãy thay đổi kiểu trả về của phương thức thành Retrofit .

Thông tin thêm trong Retrofit 2 - Hướng dẫn nâng cấp từ 1.9


ps: Nếu minSdkVersion của bạn lớn hơn 8, bạn có thể sử dụng TimeUnit.MINUTES:

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

Để biết thêm chi tiết về các đơn vị, xem TimeUnit .


Tôi không thấy setReadTimeout trong phiên bản mới của okhttp, có cách nào mới để làm việc này không?
Lion789

1
Tôi đang sử dụng okhttp3 và đối với tôi, tôi đã sử dụng mã này: new okhttp3.OkHttpClient (). NewBuilder (); okHttpClient.readTimeout (60, TimeUnit.SECONDS); okHttpClient.writeTimeout (60, TimeUnit.SECONDS); okHttpClient.connectTimeout (60, TimeUnit.SECONDS); Retrofit mới.Builder () .client (okHttpClient.build ())
lucasddaniel

@lucasddaniel Bạn có thể sử dụng câu trả lời đã chỉnh sửa và đặt tên khai báo của OkHttpClient cho trình tạo Retrofit của bạn như thế này 'Retrofit retrofitBuilderName = new Retrofit.Builder (). khách hàng (okttpclientName). xây dựng();'
f123

1
@Solace Tôi có phương pháp này : public Gson providesGson() { return new GsonBuilder().create(); }. Vì vậy, tôi làm điều này : Gson gson = module.providesGson(); RestAdapter adapter = module.providesRestAdapter(gson);. Trong đó mô-đun là một thể hiện của lớp thích hợp có tất cả các phương thức này
androidevil

1
Nếu bạn đang sử dụng OkHttp3, bạn phải sử dụng compile 'com.squareup.okhttp3:okhttp:3.x.x'trong nhập lớp, như trong câu trả lời dưới đây của Teo
NineToeNerd

82

Những câu trả lời này đã lỗi thời đối với tôi, vì vậy đây là cách nó được thực hiện.

Thêm OkHttp, trong trường hợp của tôi phiên bản là 3.3.1:

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

Sau đó trước khi xây dựng trang bị thêm của bạn, hãy làm điều này:

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();

xấu của tôi, tôi đã bỏ lỡ ()
Jonathan Aste

Điều gì sẽ xảy ra sau 60 giây đó? Chúng tôi có thể hiển thị bất kỳ lời nhắc ngay tại đó?
Arnold Brown

@ArnoldBrown Cuộc gọi trang bị thêm của bạn sẽ thất bại, cuộc gọi này sẽ gọi onFailure ()
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
Xin vui lòng một số giải thích cho câu trả lời của bạn.
humble_wolf

1

Tôi đang sử dụng Retrofit 1.9 để lấy 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);
    }

}

Nếu bạn đang sử dụng Retrofit 1.9.0 và okhttp 2.6.0, hãy thêm vào tệp Gradle của bạn.

    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'
    }

Lưu ý: Nếu bạn cần tìm nạp JSON , chỉ cần xóa khỏi mã ở trên.

.setConverter(new SimpleXMLConverter())

1

Đối với Retrofit1.9 với người dùng OkHttp3, đây là giải pháp,

.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

Đây sẽ là cách tốt nhất để đặt thời gian chờ cho mỗi dịch vụ (vượt qua thời gian chờ làm tham số)

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;
    }

Và đừng bỏ lỡ điều này cho 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);
        }
    }

Hy vọng điều này sẽ giúp được bất cứ ai.


0

Tôi tìm thấy ví dụ này

https://github.com/sapes/retrofit/issues/1557

Ở đây, chúng tôi đặt máy khách kết nối máy khách url tùy chỉnh trước khi chúng tôi xây dựng triển khai dịch vụ nghỉ ngơi 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
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Xin vui lòng cố gắng không làm đông mã của bạn với các bình luận giải thích, điều này làm giảm khả năng đọc của cả mã và các giải thích!
Filnor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.