java - OkHttp3 从不在慢速互联网上超时

标签 java android okhttp connection-timeout

首先,我已经阅读了很多关于我的问题的问题,但它从来没有给我解决方案。以下是我阅读的关于我的问题的一些问题。

我也读过这个article关于我的问题,但它也从未为我提供解决方案。

问题:

我在我的 Web 服务应用程序中使用 Okhhtp3 库。它工作正常,但当互联网连接缓慢或连接不可靠时,它会卡住并且永远不会超时或永远不会调用超时异常或失败方法。

客户端代码如下:

OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .retryOnConnectionFailure(false)
            .build();

如何在 20 秒后获取超时异常或调用失败方法?

请帮帮我。谢谢

最佳答案

正如 Trevor Halvorson 所指出的,您可以在客户端构建期间设置 callTimeout,方法如下:

OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .callTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .retryOnConnectionFailure(false)
            .build();

我已经使用 okhttp33.14.0 版本在虚拟项目中进行了个人测试:

implementation 'com.squareup.okhttp3:okhttp:3.14.0'

并设置 5 秒的超时和我的模拟器 connectionGPRSPoor connectivity 我得到

java.net.SocketExcpetion: Socket closed: timeout

enter image description here

这是我的完整虚拟 Activity :

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());
                    });
                }
            }
        });
    }
}

我也会给你我的应用 build.gradle 文件。

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'
}

关于java - OkHttp3 从不在慢速互联网上超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55122236/

相关文章:

retrofit - NetworkOnMainThread RxJava + 改造 + Lollipop+

java - java对象结构的线程安全发布?

java - 事务提交后更新查询未刷新

android - 无法在 admob 中链接我的 Android 应用

Android ByteArrayOutputStream 破坏 HTTP GET JSONArray

java - 哈希用户密码并检查Android中数据库中的哈希值

java - 如何为 JUnit 测试模拟 okhttp 响应

android - OKHTTP 无法解析主机 没有与主机名关联的地址

java - 选择字符串中的第三个数字

java - HSQLDB 数据库中神秘的完整性约束违规