Retrofit 2

时间:2018-03-16 10:21:01

标签: android retrofit retrofit2 okhttp

我面临单个API重复请求的问题, 我正在使用改造2.当我尝试调用一个API时,它击中服务器3次。 在部分小部分中多次调用相同的API。这是代码:

 public Retrofit retrofit() {
    String UrlBasePath="";

    if (mRetrofit == null) {
        if (builder == null) {
            builder = new OkHttpClient.Builder();
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request original = chain.request();
                HttpUrl httpUrl = original.url().newBuilder()
                        .build();
                String credentials = BuildConfig.ApiUserName + ":" + BuildConfig.ApiPassword;

                if (BuildConfig.ApiUserName.equals("APIUSERNAME") || BuildConfig.ApiPassword.equals("APIPASSWORD")) {
                    AnalyticsManager.sendEvent("RETROERROR", "AUTHENTICATIONFAILED", "FAILED");
                }

                final String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
                // Request customization: add request headers
                Request request = original.newBuilder()
                        .addHeader("Authorization", basic)
                        .addHeader("User-Agent", "android")
                        .method(original.method(), original.body())
                        .url(httpUrl)
                        .build();
                return chain.proceed(request);

            }
        }).connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS);

        if(BuildConfig.BUILD_TYPE.equalsIgnoreCase("debug")) {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(logging);
        }

        UrlBasePath = UrlParser.httpsUrlBasePath;

        OkHttpClient client = enableTls12OnPreLollipop(builder).build();

        mRetrofit = new Retrofit.Builder()
                .baseUrl(UrlBasePath)
                .addConverterFactory(new ToStringConverterFactory())
                .addConverterFactory(GsonConverterFactory.create(gsonMapper()))
                .client(client)
                .build();
    }
    }
    return mRetrofit;
}

在Activity:Activity code

中调用此方法
private final BmApiInterface RetroApiCall = RetroConnect.getInstance().retrofit().create(BmApiInterface.class); //global variable

Call<SingleLoginParser> loginCall = RetroApiCall.getLoginAPI(MatriidDet+"~"+Constants.APPVERSIONCODE,System.currentTimeMillis(),
                        Constants.constructApiUrlMap(new UrlParser().UrlGenerator(Constants.COMMON_LOGIN, new String[]{}))
                );
                mCallList.add(loginCall);
                RetroConnect.getInstance().AddToEnqueue(loginCall, mListener, RequestType.COMMON_LOGIN);

有人可以帮助我!!

2 个答案:

答案 0 :(得分:2)

当服务器响应缓慢且超时,然后retfofit2重试同一请求多次时,这是可能的。为防止这种情况,您必须对OkHttpClient使用.retryOnConnectionFailure(false)方法。

示例代码

OkHttpClient okHttpClient= null;
        okHttpClient = new OkHttpClient.Builder()
                .sslSocketFactory(new TLSSocketFactory(),trustManager)
                .connectTimeout(2, TimeUnit.MINUTES)
                .readTimeout(2, TimeUnit.MINUTES)
                .writeTimeout(2, TimeUnit.MINUTES)
                //.sslSocketFactory(sslSocketFactory, trustManager)
                .followRedirects(false)
                .followSslRedirects(false)
                .retryOnConnectionFailure(false)
                .cache(null)//new Cache(sContext.getCacheDir(),10*1024*1024)
                .build();

在以前的版本中,经过改版后存在一些错误并已修复:2.1.0

因此,您应该使用Retrofit2和okhttp3的更新版本:

    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    implementation 'com.squareup.okhttp3:okhttp:3.4.1' 

问题讨论:

https://github.com/square/okhttp/pull/1259#issuecomment-68430264

答案 1 :(得分:0)

您使用改造使用异步api调用,并且还对改进设置进行了一些更改。 为改造提供单独的课程。

    public static ApiClient apiClient;
private Retrofit retrofit = null;

public static ApiClient getInstance() {
    if (apiClient == null) {
        apiClient = new ApiClient();
    }
    return apiClient;
}

//private static Retrofit storeRetrofit = null;

public Retrofit getClient() {
    return getClient(null);
}

private Retrofit getClient(final Context context) {

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder client = new OkHttpClient.Builder();
    client.readTimeout(60, TimeUnit.SECONDS);
    client.writeTimeout(60, TimeUnit.SECONDS);
    client.connectTimeout(60, TimeUnit.SECONDS);
    client.addInterceptor(interceptor);
    client.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (context == null) {
                request = request
                        .newBuilder()
                        .build();
            } else {
                request = request
                        .newBuilder()
                        .addHeader("Authorization", "Bearer " + AppSetting.getStringSharedPref(context, Constants.USER_KEY_TOKEN, ""))
                        .build();
            }
            return chain.proceed(request);
        }
    });

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();


    return retrofit;
}

然后在make api界面之后调用如下..

public interface ApiInterface {
@POST("api/login")
Call<LoginResponseModel> loginCheck(@Body UserData data);

}

然后使用如下代码..

    ApiInterface apiInterface = ApiClient.getInstance().getClient().create(ApiInterface.class);
    Call<LoginResponseModel> loginResponseModelCall = apiInterface.loginCheck("yourobject or key");
    loginResponseModelCall.enqueue(new Callback<LoginResponseModel>() {
        @Override
        public void onResponse(Call<LoginResponseModel> call, Response<LoginResponseModel> response) {
            if (response != null && response.isSuccessful() && response.body() != null) {
                Toast.makeText(getApplicationContext(), response.body().getMessage(), Toast.LENGTH_SHORT).show();

            } else {
            }
        }

        @Override
        public void onFailure(Call<LoginResponseModel> call, Throwable t) {

        }
    });