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
接口的泛化能力,开发者能根据需求添加新的适配器实现。
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
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 平台类似的降级策略,下面从多个方面详细分析:
降级策略概念
降级策略通常是指在系统运行过程中,当某些高级功能无法正常使用或者资源不足时,系统会自动切换到次优方案,以保证基本功能的正常运行。在网络通信场景中,可能表现为当无法使用最新的安全协议或加密算法时,退而使用较旧但仍可用的协议或算法。
1. 多 SocketAdapter
实现
SocketAdapter
是一个接口,有多种实现类,如 AndroidSocketAdapter
、ConscryptSocketAdapter
、BouncyCastleSocketAdapter
等。每个实现类对应不同的 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
相关操作时,会遍历该列表,依次调用每个 SocketAdapter
的 isSupported()
和 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
实现。