服务生成器改造 [英] Service Generator Retrofit

查看:73
本文介绍了服务生成器改造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以帮助我理解下面的代码中的 createService 方法.我需要了解什么是方法的参数类 S 和下面的代码

Can someone help me understand the createService method in below code. I need to understand what is method's parameter Class S and the code underneath in depth

public class ServiceGenerator {

public static final String API_BASE_URL = Constant.BASE_URL;

private static OkHttpClient httpClient = new OkHttpClient();

private static Retrofit.Builder builder =
        new Retrofit.Builder()
                .baseUrl(API_BASE_URL)
                .addConverterFactory(GsonConverterFactory.create());

public static <S> S createService(Class<S> serviceClass) {
    httpClient.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            Request.Builder requestBuilder = original.newBuilder()
                    .header("cache-control","no-cache")
                    .method(original.method(), original.body());

            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    Retrofit retrofit = builder.client(httpClient).build();
    return retrofit.create(serviceClass);
}

}

推荐答案

我对此有同样的问题.在研究了几分钟之后,我意识到了这个问题.基本上,您不必使用以下代码行:

I had the same problem with this. After a few minutes studying what's going on I realized the issue. Basically you have not to use this line of code:

private static OkHttpClient httpClient = new OkHttpClient();

这是问题所在,每次您都使用类似的静态变量:

Here is the problem, using a static variable like that each time you do:

Retrofit retrofit = builder.client(httpClient).build();

您正在创建该对象的另一个相同实例,而较旧的实例正在使用相同的引用并添加N个拦截器对象,并且每个拦截器对象都是Rest客户端(请注意,< ----主要问题.因此,您必须检查HttpClient是否已制成,因此解决此问题的最终解决方案是下一个解决方案:

you are creating another same instance of the object and the older one are using the same reference and adding N interceptor objects, and each interceptor objects is a Rest client (take care about this, <---- Main problem. For that reason you must to check if the HttpClient is already made or not. So the final solution to fix this problem is the next one:

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.fastjson.FastJsonConverterFactory;
import utils.Constantes;

/**
 * Created by abeld on 19/05/2016.
 */
public class ServiceGenerator {

    public static final String API_BASE_URL = Constantes.URL_SERVER;

    private static OkHttpClient.Builder httpClient;

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(FastJsonConverterFactory.create());

    public static <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, null);
    }

    public static <S> S createService(Class<S> serviceClass, final AccessToken token) {

        if(httpClient == null){
            httpClient = new OkHttpClient.Builder();
            if (token != null) {
                httpClient.addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request original = chain.request();

                        Request.Builder requestBuilder = original.newBuilder()
                                .header("Accept", "application/json")
                                .header("Authorization", token.getTypeTokenAndToken())
                                .method(original.method(), original.body());

                        Request request = requestBuilder.build();
                        return chain.proceed(request);
                    }
                });
            }
            httpClient.connectTimeout(50, TimeUnit.SECONDS);
            httpClient.addInterceptor(addLoggin());
        }

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = builder.client(client).build();
        return retrofit.create(serviceClass);
    }

    private static HttpLoggingInterceptor addLoggin(){

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();

        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        return logging;
    }
}

如您所见,我会检查对象是否已为null,在这种情况下,只需在其他情况下跳过创建一个实例即可.

As you can see I do a check if the object is already null, in this case just create a instance in other case skip.

顺便说一句,如果您使用添加一个新的拦截器(如记录器),则可以在Android Studio控制台中看到您执行的请愿数量,如果请愿数量仅为1,则可以修复缺陷.

By the way, if you use add a new interceptor like a logger you could see in your Android Studio console the number of petitions that you do, if the number of petitions is just 1, you fixed the defect.

这篇关于服务生成器改造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆