如果我创建请求并且该请求返回4xx
错误,则Retrofit / Okhttp会一直重试该请求。我将retryOnConnectionFailure
设置为false并将超时设置为15秒,但似乎都被忽略了。我错过了什么吗?
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 :(得分:2)
此代码可以帮助您,我在Application Class中使用Retrofit并在Manifest文件中将该类用作应用程序名称标记
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'
}
答案 1 :(得分:1)
问题是retryOnConnectionFailure
不适用于408
回复,因此它仍会自动重试
答案 2 :(得分:0)
您可以尝试创建自己的retryOnConnectionFailure拦截器:
这是kotlin中的代码:
open class MaxRetryCountInterceptor(private val retryLimit: Int) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Chain): Response {
val request = chain.request()
var response = chain.proceed(request)
var tryCount = 0
while (!response.isSuccessful && tryCount < retryLimit) {
tryCount++
response = chain.proceed(request)
}
return response
}
}
response.isSuccessful
仅在代码介于200..300
之间时成功