OkHttp之AndroidPlatform类分析

OkHttp之AndroidPlatform类分析

一、AndroidPlatform 类设计

1. 概述

AndroidPlatform 是 OkHttp 针对 Android 5 到 9(API 21 到 28)平台的特定实现类。它继承自 Platform 类,同时实现 ContextAwarePlatform 接口,为 Android 平台提供定制化的网络连接、SSL 配置和证书管理等功能。

2. 关键属性

  • applicationContext :应用上下文,用于访问 Android 系统服务和资源,实现 ContextAwarePlatform 接口的属性。
  • socketAdapters :用于处理 SSLSocket 的适配器列表,包含多种不同的 SocketAdapter 实例,会根据设备支持情况进行初始化和过滤。

3. 关键方法

  • connectSocket :连接指定的 Socket 到目标地址,针对 Android 8.0(API 26)的特定 bug 进行异常处理。
  • newSSLContext :创建新的 SSLContext 实例,标记该操作是慢操作后调用父类方法。
  • trustManager :从 SSLSocketFactory 中获取 X509TrustManager 实例,遍历 socketAdapters 列表查找匹配适配器。
  • configureTlsExtensions :配置 SSLSocket 的 TLS 扩展,遍历 socketAdapters 列表查找匹配适配器进行配置。
  • getSelectedProtocol :获取 SSLSocket 协商选定的协议,遍历 socketAdapters 列表查找匹配适配器获取协议。
  • isCleartextTrafficPermitted:根据 Android 系统 API 版本判断是否允许明文流量。
  • buildCertificateChainCleaner :尝试使用 AndroidCertificateChainCleaner 构建证书链清理器,失败则调用父类方法。
  • buildTrustRootIndex :尝试通过反射调用 X509TrustManager 的方法构建信任根索引,失败则调用父类方法。

4. 类关系图

classDiagram Platform <|-- AndroidPlatform AndroidPlatform ..|> ContextAwarePlatform AndroidPlatform "1" *-- "n" SocketAdapter : uses AndroidPlatform ..> AndroidCertificateChainCleaner AndroidPlatform ..> NetworkSecurityPolicy AndroidPlatform ..> SSLContext AndroidPlatform ..> X509TrustManager AndroidPlatform ..> SSLSocketFactory AndroidPlatform ..> SSLSocket AndroidPlatform ..> Socket class Platform { <> +newSSLContext() +buildCertificateChainCleaner() +buildTrustRootIndex() +trustManager() +configureTlsExtensions() +getSelectedProtocol() +isCleartextTrafficPermitted() +log() } class ContextAwarePlatform { <> +applicationContext: Context? } class AndroidPlatform { +applicationContext: Context? -socketAdapters: List +connectSocket() +newSSLContext() +trustManager() +configureTlsExtensions() +getSelectedProtocol() +isCleartextTrafficPermitted() +buildCertificateChainCleaner() +buildTrustRootIndex() +getHandshakeServerNames() +log() +CustomTrustRootIndex +buildIfSupported() } class SocketAdapter { <> +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class AndroidCertificateChainCleaner { +buildIfSupported() } class NetworkSecurityPolicy { +getInstance() +isCleartextTrafficPermitted() }

5. 平台选择流程图

flowchart TD A[Platform.buildPlatform] --> B{平台类型?} B -->|JVM| C[JvmPlatformRegistry.findPlatform] B -->|Android| D[AndroidPlatformRegistry.findPlatform] C --> C1{Conscrypt可用?} C1 -->|是| C2[ConscryptPlatform] C1 -->|否| C3{OpenJSSE可用?} C3 -->|是| C4[OpenJSSEPlatform] C3 -->|否| C5{BouncyCastle可用?} C5 -->|是| C6[BouncyCastlePlatform] C5 -->|否| C7{JDK 9+或JDK 8 build 252+?} C7 -->|是| C8[Jdk9Platform] C7 -->|否| C9{JDK 8?} C9 -->|是| C10[Jdk8WithJettyBootPlatform] C9 -->|否| C11[默认Platform] D --> D1{Android 10+?} D1 -->|是| D2[Android10Platform] D1 -->|否| D3{Android 5 - 9?} D3 -->|是| D4[AndroidPlatform] D4 --> D41{ConscryptSocketAdapter支持?} D41 -->|是| D42[使用ConscryptSocketAdapter] D41 -->|否| D43{BouncyCastleSocketAdapter支持?} D43 -->|是| D44[使用BouncyCastleSocketAdapter] D43 -->|否| D45{AndroidSocketAdapter支持?} D45 -->|是| D46[使用AndroidSocketAdapter] D45 -->|否| D47[使用默认SocketAdapter处理] D3 -->|否| D5{API版本=0?} D5 -->|是| D6[Jdk9Platform或默认Platform] D5 -->|否| D7[抛出异常]

二、SocketAdapter 扩展设计

1. 概述

SocketAdapter 是一个接口,旨在为不同的 SSLSocket 实现提供适配能力。通过实现该接口,开发者能轻松添加新的 SSLSocket 适配逻辑,而不影响现有代码。

2. 关键方法

  • isSupported() :判断当前平台是否支持该 SocketAdapter 实现。
  • trustManager(sslSocketFactory) :从 SSLSocketFactory 中获取 X509TrustManager 实例,默认返回 null
  • matchesSocket(sslSocket) :判断给定的 SSLSocket 是否与当前 SocketAdapter 匹配。
  • matchesSocketFactory(sslSocketFactory) :判断给定的 SSLSocketFactory 是否与当前 SocketAdapter 匹配,默认返回 false
  • configureTlsExtensions(sslSocket, hostname, protocols) :配置 SSLSocket 的 TLS 扩展。
  • getSelectedProtocol(sslSocket) :获取 SSLSocket 协商选定的协议。

3. 常见实现类

  • AndroidSocketAdapter :基于现代反射的 Socket 适配器,适用于 Conscrypt 类的 SSLSocket
  • Android10SocketAdapter :适用于 Android Q(API 级别 29)及以上版本的简单非反射 Socket 适配器。
  • ConscryptSocketAdapter :当 Conscrypt 作为应用依赖直接引入时,使用的简单非反射 Socket 适配器。
  • BouncyCastleSocketAdapter :适用于 Bouncy Castle 的简单非反射 Socket 适配器。

三、SocketAdapter 泛化分析

1. 泛化概念

SocketAdapter 接口的设计具备良好的泛化能力,不同的实现类可根据具体的 SSLSocket 实现(如 Conscrypt、Bouncy Castle 等)提供适配逻辑。这种设计使得 SocketAdapter 能够灵活应对多种 SSLSocket 实现,降低了代码的耦合度,提高了可扩展性。

2. 泛化类关系图

classDiagram SocketAdapter <|-- AndroidSocketAdapter SocketAdapter <|-- Android10SocketAdapter SocketAdapter <|-- ConscryptSocketAdapter SocketAdapter <|-- BouncyCastleSocketAdapter SocketAdapter <|-- CustomSocketAdapter class SocketAdapter { <> +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class AndroidSocketAdapter { +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class Android10SocketAdapter { +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class ConscryptSocketAdapter { +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class BouncyCastleSocketAdapter { +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) } class CustomSocketAdapter { +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) }

从图中可以看出,SocketAdapter 作为接口,多个具体的适配器类实现了该接口。CustomSocketAdapter 表示开发者可以自定义的适配器类,体现了 SocketAdapter 接口的泛化能力,开发者能根据需求添加新的适配器实现。

四、AndroidPlatformSocketAdapter 的关系

1. 依赖关系

AndroidPlatform 依赖 SocketAdapter 来处理 SSLSocket 相关操作。AndroidPlatform 持有一个 socketAdapters 列表,在进行 SSLSocket 相关操作时,会遍历该列表,找到匹配的 SocketAdapter 并调用其方法。

2. 协作流程

trustManager 方法为例
sequenceDiagram participant Client participant AndroidPlatform participant SocketAdapter Client->>AndroidPlatform: trustManager(sslSocketFactory) AndroidPlatform->>AndroidPlatform: Iterate socketAdapters loop For each SocketAdapter AndroidPlatform->>SocketAdapter: matchesSocketFactory(sslSocketFactory) alt Match found SocketAdapter-->>AndroidPlatform: true AndroidPlatform->>SocketAdapter: trustManager(sslSocketFactory) SocketAdapter-->>AndroidPlatform: X509TrustManager AndroidPlatform-->>Client: X509TrustManager else No match SocketAdapter-->>AndroidPlatform: false end end alt No match found AndroidPlatform-->>Client: null end
configureTlsExtensions 方法为例
sequenceDiagram participant Client participant AndroidPlatform participant SocketAdapter Client->>AndroidPlatform: configureTlsExtensions(sslSocket, hostname, protocols) AndroidPlatform->>AndroidPlatform: Iterate socketAdapters loop For each SocketAdapter AndroidPlatform->>SocketAdapter: matchesSocket(sslSocket) alt Match found SocketAdapter-->>AndroidPlatform: true AndroidPlatform->>SocketAdapter: configureTlsExtensions(sslSocket, hostname, protocols) SocketAdapter-->>AndroidPlatform: Operation completed AndroidPlatform-->>Client: Operation completed else No match SocketAdapter-->>AndroidPlatform: false end end alt No match found AndroidPlatform-->>Client: No suitable adapter found end

AndroidPlatform 通过 SocketAdapter 泛化最终实现了与 JVM 平台类似的降级策略,下面从多个方面详细分析:

降级策略概念

降级策略通常是指在系统运行过程中,当某些高级功能无法正常使用或者资源不足时,系统会自动切换到次优方案,以保证基本功能的正常运行。在网络通信场景中,可能表现为当无法使用最新的安全协议或加密算法时,退而使用较旧但仍可用的协议或算法。

AndroidPlatformSocketAdapter 实现降级策略的方式

1. 多 SocketAdapter 实现

SocketAdapter 是一个接口,有多种实现类,如 AndroidSocketAdapterConscryptSocketAdapterBouncyCastleSocketAdapter 等。每个实现类对应不同的 SSLSocket 实现或不同的 Android 平台版本,这就为降级提供了多种备选方案。

classDiagram SocketAdapter <|-- AndroidSocketAdapter SocketAdapter <|-- ConscryptSocketAdapter SocketAdapter <|-- BouncyCastleSocketAdapter SocketAdapter <|-- Android10SocketAdapter class SocketAdapter { <> +isSupported() +trustManager(sslSocketFactory) +matchesSocket(sslSocket) +matchesSocketFactory(sslSocketFactory) +configureTlsExtensions(sslSocket, hostname, protocols) +getSelectedProtocol(sslSocket) }

2. 动态选择适配器

AndroidPlatform 持有一个 socketAdapters 列表,在进行 SSLSocket 相关操作时,会遍历该列表,依次调用每个 SocketAdapterisSupported()matchesSocket() 等方法,找到第一个匹配且支持的 SocketAdapter 来处理操作。如果当前的适配器不支持,就尝试下一个,直到找到合适的适配器或者遍历完所有适配器。

sequenceDiagram participant Client participant AndroidPlatform participant Adapter1 participant Adapter2 participant Adapter3 Client->>AndroidPlatform: configureTlsExtensions(sslSocket, ...) AndroidPlatform->>Adapter1: isSupported() Adapter1-->>AndroidPlatform: false AndroidPlatform->>Adapter2: isSupported() Adapter2-->>AndroidPlatform: true AndroidPlatform->>Adapter2: matchesSocket(sslSocket) Adapter2-->>AndroidPlatform: true AndroidPlatform->>Adapter2: configureTlsExtensions(sslSocket, ...) Adapter2-->>AndroidPlatform: Success AndroidPlatform-->>Client: Success

3. 降级效果

当系统环境发生变化,比如 Android 版本升级、依赖库缺失等,导致某些 SocketAdapter 不再支持时,AndroidPlatform 会自动选择其他可用的 SocketAdapter,从而保证网络通信功能的正常运行。这与 JVM 平台的降级策略类似,JVM 平台在遇到安全协议不支持、证书验证失败等问题时,也会尝试使用其他方案来保证通信的基本功能。

与 JVM 平台降级策略的相似性

  • 多方案选择 :JVM 平台也有多种安全协议、加密算法和网络库的实现可供选择。当首选方案不可用时,会尝试其他方案。例如,当 TLS 1.3 不可用时,会降级到 TLS 1.2。AndroidPlatform 同样通过 SocketAdapter 提供了多种适配方案,根据实际情况选择合适的适配器。
  • 自动降级 :JVM 平台和 AndroidPlatform 都能自动检测环境变化,在发现当前方案不可行时,自动切换到备用方案,无需人工干预。

综上所述,AndroidPlatform 通过 SocketAdapter 泛化实现了与 JVM 平台类似的降级策略,提高了系统的健壮性和兼容性。

五、总结

AndroidPlatform 通过组合多个 SocketAdapter 实例,实现了对不同 SSLSocket 实现的灵活支持。SocketAdapter 接口的泛化设计使得新的 SSLSocket 适配逻辑可以方便地扩展,提高了代码的可维护性和可扩展性。这种设计模式符合开闭原则,对扩展开放,对修改关闭。开发者可以根据具体需求实现新的 SocketAdapter 类,以支持更多类型的 SSLSocket 实现。

相关推荐
hsx6664 分钟前
Android 内存泄漏避坑
android
whysqwhw12 分钟前
OkHttp之okhttp-bom模块的分析
android
餐桌上的王子21 分钟前
Android 构建可管理生命周期的应用(二)
android
幽你一默1 小时前
Android 版本差异速查表(开发者视角)
android
不萌1 小时前
android 项目中的屏幕适配方案
android
幽你一默1 小时前
Android开发三分钟读懂mvc,mvp,mvvm,mvi
android
小仙女喂得猪3 小时前
2025 源码应用: Retrofit之动态更换BaseUrl
android·android studio
AmazingMQ3 小时前
Android 13----在framworks层映射一个物理按键
android
小李飞飞砖4 小时前
Android 插件化实现原理详解
android
m0_597345314 小时前
【Android】安卓四大组件之广播接收器(Broadcast Receiver):从基础到进阶
android·java·boradcast·安卓四大组件