2017-07-07 345 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