You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11+应用频繁崩溃:java.net.SocketException: Connection Reset求助

应用在Android 11+上频繁因java.net.SocketException: Connection Reset崩溃排查

问题概述

  • 应用频繁抛出java.net.SocketException: Connection Reset并崩溃,堆栈跟踪中无自研代码,怀疑是依赖库兼容性问题
  • 该问题仅出现在Android 11及以上系统,使用Retrofit2进行网络请求
  • 已尝试增加超时时间,但偶尔仍会出现Socket Closed异常

堆栈信息

Fatal Exception: java.net.SocketException: Connection reset 
at java.net.SocketInputStream.read(SocketInputStream.java:215) 
at java.net.SocketInputStream.read(SocketInputStream.java:144) 
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945) 
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909) 
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824) 
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797) 
at okio.Okio$2.read(Okio.java:140) 
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237) 
at okio.RealBufferedSource.read(RealBufferedSource.java:47) 
at okhttp3.internal.http1.Http1Codec$AbstractSource.read(Http1Codec.java:363) 
at okhttp3.internal.http1.Http1Codec$ChunkedSource.read(Http1Codec.java:453) 
at okio.RealBufferedSource.read(RealBufferedSource.java:47) 
at okio.ForwardingSource.read(ForwardingSource.java:35) 
at retrofit2.OkHttpCall$ExceptionCatchingResponseBody$1.read(OkHttpCall.java:288) 
at okio.RealBufferedSource$1.read(RealBufferedSource.java:439) 
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:291) 
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:355) 
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:181) 
at java.io.InputStreamReader.read(InputStreamReader.java:184) 
at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.java:259) 
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1289) 
at com.google.gson.stream.JsonReader.nextQuotedValue(JsonReader.java:1029) 
at com.google.gson.stream.JsonReader.nextString(JsonReader.java:814) 
at com.google.gson.internal.bind.TypeAdapters$15.read(TypeAdapters.java:380) 
at com.google.gson.internal.bind.TypeAdapters$15.read(TypeAdapters.java:368) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61) 
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39) 
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27) 
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225) 
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121) 
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206) 
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:920)

排查方向与解决方案

1. 适配Android 11+网络行为变更

Android 11对网络连接引入了更严格的限制,重点检查:

  • 确认服务器TLS配置,需兼容Android 11默认启用的TLS 1.3,同时保留TLS 1.2支持
  • 升级OkHttp到4.9.0及以上版本,该版本针对Android 11的网络特性做了兼容性优化

2. 调整OkHttp连接池配置

连接池中的空闲连接可能被系统或服务器主动关闭,导致复用连接时出错:

  • 缩短空闲连接存活时间,避免复用已失效的连接,配置示例:
ConnectionPool connectionPool = new ConnectionPool(
    5, // 最大空闲连接数
    30, TimeUnit.SECONDS // 空闲连接存活时间
);
OkHttpClient client = new OkHttpClient.Builder()
    .connectionPool(connectionPool)
    .build();

3. 修复SSL/TLS兼容性问题

堆栈中出现Conscrypt相关代码,可能是TLS握手兼容性问题:

  • 强制OkHttp使用TLS 1.2,规避TLS 1.3的适配问题,实现自定义SSLSocketFactory:
public class SSLSocketFactoryCompat extends SSLSocketFactory {
    private final SSLSocketFactory delegate;

    public SSLSocketFactoryCompat() {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, null, null);
            delegate = sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        Socket socket = delegate.createSocket(s, host, port, autoClose);
        ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        Socket socket = delegate.createSocket(host, port);
        ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
        Socket socket = delegate.createSocket(host, port, localHost, localPort);
        ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        Socket socket = delegate.createSocket(host, port);
        ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        Socket socket = delegate.createSocket(address, port, localAddress, localPort);
        ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
        return socket;
    }
}

// 应用到OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
    .sslSocketFactory(new SSLSocketFactoryCompat(), X509TrustManagerExtensions.getDefault())
    .build();

4. 完善异常捕获与重试机制

确保网络请求异常被正确处理,避免崩溃:

  • 在Retrofit的onFailure回调中显式捕获SocketException,防止未捕获异常导致崩溃
  • 实现重试拦截器,针对Connection Reset和Socket Closed异常自动重试:
public class RetryInterceptor implements Interceptor {
    private static final int MAX_RETRIES = 3;

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        IOException exception = null;

        for (int i = 0; i < MAX_RETRIES; i++) {
            try {
                Response response = chain.proceed(request);
                if (response.isSuccessful()) {
                    return response;
                }
            } catch (IOException e) {
                exception = e;
                if (isRetryable(e)) {
                    continue;
                }
                break;
            }
        }

        throw exception != null ? exception : new IOException("Max retries exceeded");
    }

    private boolean isRetryable(IOException e) {
        return e instanceof SocketException && 
               (e.getMessage().contains("Connection reset") || e.getMessage().contains("Socket closed"));
    }
}

// 添加到OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new RetryInterceptor())
    .build();

内容的提问来源于stack exchange,提问作者gogita kupatadze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:01:03