一般情况下,Glide都是能正常访问Https图片的,因为日常的都是权威的CA证书,手机会自带这些证书,就认证过了, 但是如果服务器用的是自签证书,这个时候就无法访问了,会报如下错误
javax.net.ssl.SSLHandshakeException(java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.)
接下来我们看看如何解决这个问题:
- 创建一个能忽略https的OkhttpClient,
- 替换Glide的加载器
创建一个能忽略https的OkhttpClient
这个网上有很多,我这简单贴下我的代码
object UnsafeOkHttpClient {
/**
* 创建一个忽略SSL校验的OkHttpClient
* @param hostArray 你要忽略的域名,空数组 信任所有域名
*/
fun getUnsafeOkHttpClientByUrl( hostArray:Array<String>): OkHttpClient {
try {
Log.d("TAG", "忽略 getUnsafeOkHttpClient: ")
// Create a trust manager that does not validate certificate chains
val trustAllCerts = arrayOf<TrustManager>(TrustAllCertsTrustManager())
// Install the all-trusting trust manager
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
// Create an ssl socket factory with our all-trusting manager
val sslSocketFactory = sslContext.socketFactory
val builder = OkHttpClient.Builder()
builder.sslSocketFactory(
sslSocketFactory,
(trustAllCerts[0] as X509TrustManager)
)
builder.hostnameVerifier(CustomHostnameVerifier(hostArray))
val okHttpClient = builder.build()
return okHttpClient
} catch (e: NoSuchAlgorithmException) {
throw IllegalStateException(e)
} catch (e: KeyManagementException) {
throw IllegalStateException(e)
}
}
}
class CustomHostnameVerifier(private val allowedHost: Array<String>) : HostnameVerifier {
override fun verify(hostname: String, session: SSLSession): Boolean {
if (allowedHost.isEmpty()) {
//空数组,则完全不拦截
return true
}
for (host in allowedHost) {
Log.d("TAG", " https verify:${host} $hostname ")
if (host.contains(hostname)) {
return true
}
}
return false
}
}
替换Glide的加载器
在我们的AppLication中加入以下代码
Glide.get(this).registry.replace(
GlideUrl::class.java,
InputStream::class.java, OkHttpUrlLoader.Factory(UnsafeOkHttpClient.getUnsafeOkHttpClientByUrl(arrayOf()))
)
到这就结束了,很简单