If I create a request and that request returns a 4xx
error Retrofit/Okhttp keeps retrying the request. I have set retryOnConnectionFailure
to false and set a timeout of 15 seconds but that all seems to be ignored. did I miss something?
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();
}
I am using retrofit 2.3.0
and okhttp version 3.8.1
Edit
One thing I do see is that if I set a timeout of 5 seconds it works perfectly keeps retrying for 5 seconds then gives me a failure but if I bump it up to 10 seconds it just keeps going and finally stops around 2 minutes.
The issue is that retryOnConnectionFailure
does not apply to 408
responses so it will still retry those automatically
This code may help you, I use Retrofit in Application Class and use that class in Manifest file as application name tag
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);
}
}
And in Manifest file
<?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>
And finally 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'
}
you can try creating your own retryOnConnectionFailure interceptor:
here is code in 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
is successful only when code is between 200..300
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With