如何在 Retrofit 库中设置超时时间?

214

我在我的应用程序中使用 Retrofit 库,并且我想设置一个60秒的超时时间。Retrofit有没有一些方法可以实现这个?

我是这样设置Retrofit的:


这是我设置Retrofit的方式:

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

我如何设置超时时间?

10个回答

366

您可以在底层的HTTP客户端上设置超时时间。如果您没有指定客户端,Retrofit将创建一个默认连接和读取超时时间的客户端。要设置自己的超时时间,您需要配置自己的客户端并将其提供给RestAdapter.Builder

一个可选方案是使用Square提供的OkHttp客户端。

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

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

更多信息请参见超时


编辑2

2.x.x以后的Retrofit版本也使用了构建器模式,因此将上面的返回块更改为:

return new Retrofit.Builder()
    .baseUrl(BuildConfig.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(okHttpClient)
    .build();
如果使用像我的providesRestAdapter方法一样的代码,则将该方法的返回类型更改为Retrofit

有关更多信息,请参见Retrofit 2 ——从1.9升级指南


附:如果您的minSdkVersion大于8,可以使用TimeUnit.MINUTES

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

有关单位的更多详细信息,请参见TimeUnit


我在新版本的okhttp中没有看到setReadTimeout方法,有什么新的实现方式吗? - Lion789
2
我正在使用okhttp3,对于我来说,我已经使用了这段代码: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 你可以使用编辑过的答案,并将 OkHttpClient 的声明名称放置到 Retrofit 构建器中,如下所示 'Retrofit retrofitBuilderName = new Retrofit.Builder(). client(okttpclientName). build();' - f123
你在这个方法中传递的 gson 对象是从哪里获取的?我按照教程走到了这一步,使用 RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(url).build(); 创建了 RestAdapter。但是我的类中没有任何 Gson 对象,尽管我已经在项目中包含了 gson 和 converter-gson 库。 - Solace
1
@Solace 我有这样一个方法: public Gson providesGson() { return new GsonBuilder().create(); }. 所以我做了这个:Gson gson = module.providesGson(); RestAdapter adapter = module.providesRestAdapter(gson);。其中,module是一个合适的类的实例,该类拥有所有这些方法。 - androidevil
1
如果您正在使用OkHttp3,则必须在gradle导入中使用compile 'com.squareup.okhttp3:okhttp:3.x.x',就像Teo在下面的答案中所示。 - NineToeNerd

96

这些答案对我来说已经过时了,所以这是它的解决方法。

添加OkHttp,我的情况下版本是3.3.1

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

在构建Retrofit之前,请执行以下操作:

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

我的错,我漏掉了括号。 - Jonathan Aste
那60秒后会发生什么?我们能在那里显示任何提示吗? - Arnold Brown
@ArnoldBrown,您的retrofit调用将失败,这将调用onFailure()函数。 - C. Skjerdal

11
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

10

Kotlin中的做法:

首先,您应该创建一个OkHttp客户端并将其添加到Retrofit构建器中。

fun create(): Retrofit { 

        val client = OkHttpClient.Builder()
            .readTimeout(60,TimeUnit.SECONDS)
            .build()


        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

4

Kotlin中可以通过以下方法配置retrofit2的超时时间:

创建OkHttpClient对象(默认超时时间为10秒)。

val okHttpClient = OkHttpClient.Builder()
    .connectTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build()

然后将这个对象添加到你的Retrofit构建器中。

val retrofit = Retrofit.Builder()
    .addConverterFactory(ScalarsConverterFactory.create())
    .client(okHttpClient)
    .baseUrl(BASE_URL)
    .build()

从这个包中导入TimeUnit

import java.util.concurrent.TimeUnit

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
我找到了这个例子。

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

在这里,我们在构建API rest服务实现之前设置自定义URL客户端连接客户端。

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

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

    }
}

-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
虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议原因。请尽量不要在代码中添加过多的解释性注释,这会降低代码和解释的可读性! - Filnor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接