Bagaimana cara mengatur batas waktu di perpustakaan Retrofit?

180

Saya menggunakan Retrofit perpustakaan di aplikasi saya, dan saya ingin menetapkan batas waktu 60 detik. Apakah Retrofit punya cara untuk melakukan ini?

Saya mengatur Retrofit dengan cara ini:

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

Bagaimana saya bisa mengatur batas waktu?

androidevil
sumber

Jawaban:

320

Anda dapat mengatur batas waktu pada klien HTTP yang mendasarinya. Jika Anda tidak menentukan klien, Retrofit akan membuatnya dengan koneksi default dan batas waktu baca. Untuk mengatur batas waktu Anda sendiri, Anda perlu mengonfigurasi klien Anda sendiri dan menyediakannya ke InternetRestAdapter.Builder .

Opsi adalah menggunakan klien OkHttp , juga dari Square.

1. Tambahkan ketergantungan perpustakaan

Di build.gradle, sertakan baris ini:

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

Di mana x.x.xversi perpustakaan yang diinginkan.

2. Atur klien

Misalnya, jika Anda ingin menetapkan batas waktu 60 detik, lakukan cara ini untuk Retrofit sebelum versi 2 dan Okhttp sebelum versi 3 ( UNTUK VERSI YANG BARU, LIHAT EDIT ):

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

EDIT 1

Untuk versi okhttp sejak itu 3.x.x, Anda harus mengatur ketergantungan seperti ini:

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

Dan atur klien menggunakan pola builder:

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

Info lebih lanjut di Timeout


EDIT 2

Versi retrofit 2.x.xjuga menggunakan pola builder, jadi ubah blok balik di atas menjadi ini:

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

Jika menggunakan kode seperti providesRestAdaptermetode saya , maka ubah jenis metode pengembalian ke Retrofit .

Info lebih lanjut di Retrofit 2 - Panduan Upgrade dari 1.9


ps: Jika minSdkVersion Anda lebih besar dari 8, Anda dapat menggunakan TimeUnit.MINUTES:

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

Untuk detail lebih lanjut tentang unit, lihat TimeUnit .

androidevil
sumber
Saya tidak melihat setReadTimeout di versi baru okhttp, ada cara baru untuk melakukan ini?
Lion789
1
Saya menggunakan okhttp3, dan bagi saya saya telah menggunakan kode ini: new okhttp3.OkHttpClient (). NewBuilder (); okHttpClient.readTimeout (60, TimeUnit.SECONDS); okHttpClient.writeTimeout (60, TimeUnit.SECONDS); okHttpClient.connectTimeout (60, TimeUnit.SECONDS); new Retrofit.Builder () .client (okHttpClient.build ())
lucasddaniel
@lucasddaniel Anda dapat menggunakan jawaban yang sudah diedit dan menempatkan nama OkHttpClient yang dinyatakan ke pembuat Retrofit Anda seperti 'Retrofit retrofitBuilderName = new Retrofit.Builder (). client (okttpclientName). membangun();'
f123
1
@Solace Saya memiliki metode thid: public Gson providesGson() { return new GsonBuilder().create(); }. Jadi saya melakukan ini: Gson gson = module.providesGson(); RestAdapter adapter = module.providesRestAdapter(gson);. Di mana modul adalah turunan dari kelas yang tepat yang memiliki semua metode ini
androidevil
1
Jika Anda menggunakan OkHttp3, Anda harus menggunakan compile 'com.squareup.okhttp3:okhttp:3.x.x'impor gradle seperti pada jawaban di bawah ini oleh Teo
NineToeNerd
82

Jawaban ini sudah usang bagi saya, jadi inilah cara kerjanya.

Tambahkan OkHttp, dalam kasus saya versinya adalah 3.3.1:

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

Lalu sebelum membangun Retrofit Anda, lakukan ini:

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();
Teo Inke
sumber
salahku, aku melewatkan ()
Jonathan Aste
apa yang akan terjadi setelah 60 detik itu? Bisakah kita menunjukkan prompt di sana?
Arnold Brown
@ArnoldBrown Panggilan retrofit Anda akan gagal yang akan memanggil 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'
Pembantu Android
sumber
4
Tolong beberapa jawaban untuk jawaban Anda.
humble_wolf
1

Saya menggunakan Retrofit 1.9 untuk mendapatkan 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);
    }

}

Jika Anda menggunakan Retrofit 1.9.0 dan okhttp 2.6.0, tambahkan ke file Gradle Anda.

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

Catatan: Jika Anda perlu mengambil JSON , hapus saja dari kode di atas.

.setConverter(new SimpleXMLConverter())
bheatcoker
sumber
1

Untuk Retrofit1.9 dengan pengguna OkHttp3, ini solusinya,

.setClient(new Ok3Client(new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build()))
asozcan
sumber
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);

    }
}
Aks4125
sumber
0

Ini akan menjadi cara terbaik, untuk mengatur batas waktu untuk setiap layanan (melewati batas waktu sebagai parameter)

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

Dan jangan lewatkan ini untuk 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);
        }
    }

Semoga ini bisa membantu siapa saja.

Ruben Caster
sumber
0

Saya menemukan contoh ini

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

Di sini kami menetapkan klien koneksi klien url khusus sebelum sebelum kami membangun implementasi layanan rest 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;
        }
    }
Yan Khonski
sumber
-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'
Pembantu Android
sumber
2
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Tolong juga cobalah untuk tidak membuat kerumunan kode Anda dengan komentar penjelasan, ini mengurangi keterbacaan kode dan penjelasan!
Filnor