2017-07-07 2101 views
6

如果我创建了一个请求并且该请求返回4xx错误Retrofit/Okhttp会不断重试请求。我已将retryOnConnectionFailure设置为false,并将超时设置为15秒,但似乎都被忽略。我错过了什么?Okhttp总是重试失败的连接

private static OkHttpClient getClient() { 
     return new OkHttpClient.Builder() 
       .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE)) 
       .readTimeout(15, TimeUnit.SECONDS) 
       .connectTimeout(15, TimeUnit.SECONDS) 
       .retryOnConnectionFailure(false) 
       .addInterceptor(chain -> { 
        Request request = chain.request() 
          .newBuilder() 
          .build(); 

        return chain.proceed(request); 
       }).build(); 
    } 

    public static Retrofit getRetrofitClient(Gson gson){ 
     Retrofit.Builder builder = new Retrofit.Builder() 
       .baseUrl(baseUrl) 
       .client(OkHttpLogger.getClient()); 
     if(gson != null){ 
      builder.addConverterFactory(GsonConverterFactory.create(gson)); 
     }else{ 
      builder.addConverterFactory(GsonConverterFactory.create()); 
     } 

     return builder.build(); 
    } 

我使用改装2.3.0和okhttp版本3.8.1

编辑

一个我看到的是,如果我设置了5秒的超时它完美地保持重试5秒然后给我一个失败,但如果我碰到了10秒,它只是继续前进,最后停止约2分钟。

+0

您的拦截器是否负责允许请求继续?作为禁用静默请求重试的已知开关,您正确实施'retryOnConnectionFailure(false)'。 –

+0

@ M.Palsich删除拦截器没有效果。我所看到的一件事是,如果我设置了5秒的超时时间,它完美地保持了5秒的重试时间,然后给了我一个失败,但是如果我将它撞到10秒钟,它会继续前进,最后停止约2分钟。 – tyczj

+0

您是否在具有自己的TCP SYN重试设置的环境中存在的模拟器中进行测试?例如,Linux可以设置自己的TCP SYN重试限制。 –

回答

1

问题是retryOnConnectionFailure不适用到408响应,所以它仍然会自动重试那些

2

此代码可以帮助你,我用改造的应用类别及使用该类清单文件的应用程序名称标签

public final class Application extends MultiDexApplication { 

public static Retrofit retrofit; 
public static String base_URL = "http://mds.devsiteurl.com/"; 

public static final String TAG = Application.class.getSimpleName(); 

private static Application mInstance; 

public static synchronized Application getInstance() { 
    return mInstance; 
} 
@Override 
public void onCreate() { 
    super.onCreate(); 

    mInstance = this; 
    MultiDex.install(this); 

    Gson gson = new GsonBuilder() 
      .setLenient() 
      .create(); 

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

    retrofit = new Retrofit.Builder() 
      .baseUrl(base_URL) 
      .client(okHttpClient) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .addConverterFactory(GsonConverterFactory.create(gson)) 
      .build(); 
} 
@Override 
protected void attachBaseContext(Context base) { 
    super.attachBaseContext(base); 
    MultiDex.install(this); 
} 
} 

而且在清单文件

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.mds.foundation.mdsfoundation"> 

<uses-permission android:name="android.permission.INTERNET" /> 

<application 
    android:name=".Application" 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:roundIcon="@mipmap/ic_launcher_round" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <meta-data 
     android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 
    <meta-data 
     android:name="com.google.android.geo.API_KEY" 
     android:value="@string/google_apis_keys" /> 

    <activity android:name=".activity.MainActivity" /> 
    <activity 
     android:name=".activity.CenterOfExcellenceActivity" 
     android:windowSoftInputMode="adjustPan" /> 
    <activity android:name=".activity.SplashScreenActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

</application> 

</manifest> 

最后gradle.build

apply plugin: 'com.android.application' 

android { 
compileSdkVersion 25 
buildToolsVersion "25.0.3" 
defaultConfig { 
    applicationId "com.mds.foundation.mdsfoundation" 
    minSdkVersion 19 
    targetSdkVersion 25 
    versionCode 1 
    versionName "1.0" 
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 
    multiDexEnabled true //this line is important 
} 
buildTypes { 
    release { 
     minifyEnabled false 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
    } 
} 
packagingOptions { 

    exclude 'META-INF/DEPENDENCIES.txt' 
    exclude 'META-INF/LICENSE.txt' 
    exclude 'META-INF/NOTICE.txt' 
    exclude 'META-INF/NOTICE' 
    exclude 'META-INF/LICENSE' 
    exclude 'META-INF/DEPENDENCIES' 
    exclude 'META-INF/notice.txt' 
    exclude 'META-INF/license.txt' 
    exclude 'META-INF/dependencies.txt' 
    exclude 'META-INF/LGPL2.1' 
} 
useLibrary 'org.apache.http.legacy' 
} 

dependencies { 
compile fileTree(include: ['*.jar'], dir: 'libs') 
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
    exclude group: 'com.android.support', module: 'support-annotations' 
}) 
compile('org.apache.httpcomponents:httpmime:4.3.6') { 
    exclude module: 'httpclient' 
} 
compile 'org.apache.httpcomponents:httpclient-android:4.3.5' 
compile 'com.android.support:appcompat-v7:25.3.1' 
compile 'com.android.support.constraint:constraint-layout:1.0.1' 
compile 'com.android.support:design:25.3.1' 
compile 'com.android.support:support-v4:25.3.1' 

//refrofit 
compile 'com.squareup.retrofit2:retrofit:2.1.0' 
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' 
compile 'com.squareup.retrofit2:converter-gson:2.1.0' 
compile 'com.android.support:multidex:1.0.1' 
compile 'com.google.code.gson:gson:2.6.2' 
compile 'com.squareup.okhttp3:okhttp:3.2.0' 
compile 'com.squareup.picasso:picasso:2.5.2' 
testCompile 'junit:junit:4.12' 
} 
+0

这没有帮助,它基本上是我有的 – tyczj

+0

您是否在应用程序类中扩展了'MultiDexApplication'? –

+0

是的,但这与使用okhttp和改造无关 – tyczj