Tout d'abord, j'ai lu tant de questions concernant ma question mais cela ne me donne jamais la solution. Voici quelques-unes des questions que j'ai lues concernant ma question.
J'ai également lu ceci article concernant ma question mais il ne m'a jamais non plus fourni la solution.
Problème:
J'utilise la bibliothèque Okhhtp3 dans mon application pour les services Web. Cela fonctionne bien, mais lorsque la connexion Internet est lente ou peu fiable, elle est bloquée et n'expire jamais ou n'appelle jamais l'exception d'expiration de délai d'attente ou la méthode d'échec.
Voici le code client:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.build();
Comment obtenir l'exception de délai d'expiration ou la méthode d'échec appelée après 20 secondes?
Aidez-moi, s'il vous plaît. Merci
Comme l'a souligné Trevor Halvorson, vous pouvez définir callTimeout
pendant le générateur de client, de cette manière:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.callTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.build();
J'ai personnellement testé dans un projet factice en utilisant la version 3.14.0
de okhttp3
:
implementation 'com.squareup.okhttp3:okhttp:3.14.0'
Et en définissant un délai d'expiration de 5 secondes et mon émulateur connexion à [~ # ~] gprs [~ # ~] et Médiocre connectivité Je reçois
Java.net.SocketExcpetion: Socket closed: timeout
Ceci est mon activité factice complète :
package com.example.shadowsheep.myapplication;
import Android.os.Bundle;
import Android.util.Log;
import Android.widget.TextView;
import Java.io.IOException;
import Java.io.InterruptedIOException;
import Java.util.concurrent.TimeUnit;
import androidx.appcompat.app.AppCompatActivity;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView helloTextView = findViewById(R.id.helloTextView);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5, TimeUnit.SECONDS)
.callTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
.build();
Request request = new Request.Builder()
.url("https://www.versionestabile.it/blog")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Log.d("OKHTTP3", e.getMessage());
// You get this failure
runOnUiThread(() -> helloTextView.setText("TIMEOUT - FAILURE -> " + e.getMessage()));
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try {
final String _body = response.body().string();
Log.d("OKHTTP3", _body);
runOnUiThread(() -> {
helloTextView.setText(_body);
});
} catch (InterruptedIOException e) {
runOnUiThread(() -> {
// Or this exception depending when timeout is reached
helloTextView.setText("TIMEOUT EXCEPTION->"+ e.getCause() + ": " + e.getMessage());
});
}
}
});
}
}
Je te donnerai aussi mon application build.gradle
fichier.
apply plugin: 'com.Android.application'
Android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.shadowsheep.myapplication"
minSdkVersion 24
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.2-alpha02'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
implementation 'com.squareup.okhttp3:okhttp:3.14.0'
}
Mon cas de test ne fonctionnera pas trop, cela prend plus de 30 secondes à chaque fois:
gradle:
implementation 'com.squareup.okhttp3:okhttp:3.12.2'
defaultConfig {
minSdkVersion 16
targetSdkVersion 26
}
compileSdkVersion 27
buildToolsVersion '28.0.3'
Java:
public static class CheckIpAsyncTask extends util.Android.os.AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try {
Logger.i(TAG, "API::FBD::checkIpInfo, API_IPINFO = " + API_IPINFO);
if (BuildConfig.DEBUG) {
//ThreadUtil.sleep(10 * TimeUtil.SECOND);
}
Request req = new Request.Builder()
.get()
.url(API_IPINFO)
.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.SECONDS)
.callTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.writeTimeout(2, TimeUnit.SECONDS)
.build();
Response response = client.newCall(req).execute();
mHttpCode = response.code();
if (mHttpCode == HttpURLConnection.HTTP_OK) {
boolean appConnected = ServerHelper.checkAppConnected();
if (!appConnected) {
JSONObject res = new JSONObject(response.body().string().trim());
mCountry = res.getString("country").toLowerCase();
mIp = res.getString("ip").toLowerCase();
Logger.i(TAG, "API::FBD::checkIpInfo, res = " + res);
PreferenceHelper.get(mContext).setIpInfoApiCountry(mCountry);
PreferenceHelper.get(mContext).setIpInfoApiHost(mIp);
}
}
} catch (Java.io.InterruptedIOException interruptedIOException) {
Logger.e(TAG, "API::FBD::checkIpInfo, InterruptedIOException=" + interruptedIOException);
} catch (Throwable ignored) {
Logger.e(TAG, "API::FBD::checkIpInfo, Throwable=" + ignored);
}
return null;
}
journaux:
04-04 06:25:06.940 4492-4645/? I/Toolbox: [PLACE] at com.xy.ui.FbdUtil$CheckIpAsyncTask.doInBackground(FbdUtil.Java:98)
[FbdUtil]API::FBD::checkIpInfo, API_IPINFO = http://api.z.com:30070/servers/ipinfo
04-04 06:25:34.960 4492-4645/? E/Toolbox: [PLACE] at com.xy.ui.FbdUtil$CheckIpAsyncTask.doInBackground(FbdUtil.Java:129)
[FbdUtil]API::FBD::checkIpInfo, InterruptedIOException=Java.io.InterruptedIOException: timeout
se connecte à Emulator Nexus 6 (Android version 8.0):
04-04 06:52:44.696 2624-3950/? I/Toolbox: [PLACE] at com.xy.ui.FbdUtil$CheckIpAsyncTask.doInBackground(FbdUtil.Java:98)
[FbdUtil]API::FBD::checkIpInfo, API_IPINFO = http://api.z.com:30070/servers/ipinfo
04-04 06:53:59.886 2624-3175/? E/Toolbox: [PLACE] at com.xy.ui.ForbiddenUtil$CheckIpAsyncTask.doInBackground(FbdUtil.Java:129)
[FbdUtil]API::FBD::checkIpInfo, InterruptedIOException=Java.io.InterruptedIOException: timeout
Enfin, la solution de Dmitry Zenovich dans 'Question 6' fonctionne pour moi:
.dns(hostname -> Single.fromCallable(() -> Arrays.asList(InetAddress.getAllByName(hostname)))
.timeout(2, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.onErrorReturnItem(new ArrayList<>())
.blockingGet())