前言
在android應(yīng)用中,Glide這個(gè)工具庫(kù)想必大家已經(jīng)很熟悉了,它主要是用來(lái)加載和顯示圖片的篙螟。最近項(xiàng)目服務(wù)器url由http切換到https众旗,所有使用Glide加載網(wǎng)絡(luò)圖片的地方都失敗听皿,原因是Glide默認(rèn)是http請(qǐng)求查辩。
也就是說(shuō)羔挡,想用Gilde加載自簽名的https圖片买优,必須修改Glide加載圖片的方法券犁。本文通過(guò)使用okhttp信任自簽名證書(shū)的方法來(lái)修改GlideModule來(lái)實(shí)現(xiàn)轮锥。
1.下載com.github.bumptech.glide:okhttp.integration:1.4.0@aar包
可以通過(guò)在buile.gradle中添加依賴com.github.bumptech.glide:okhttp-integration:1.4.0@aar下載,下載后的文件在 “C盤(pán)/用戶/用戶名/.gradle/caches/modules-2/files-2.1下面”(下載完后記得把依賴刪掉)
2.拷貝其中三個(gè)類OkHttpGlideModule击蹲,OkHttpUrlLoader纽绍,OkHttpStreamFetcher到工程中
OkHttpGlideModule.class
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.GlideModule;
import com.changhong.park.pda.utils.HTTPSUtils;
import java.io.InputStream;
/**
* A {@link GlideModule} implementation to replace Glide's default
* {@link java.net.HttpURLConnection} based {@link com.bumptech.glide.load.model.ModelLoader} with an OkHttp based
* {@link com.bumptech.glide.load.model.ModelLoader}.
*
* <p>
* If you're using gradle, you can include this module simply by depending on the aar, the module will be merged
* in by manifest merger. For other build systems or for more more information, see
* {@link GlideModule}.
* </p>
*/
public class OkHttpGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// Do nothing.
}
@Override
public void registerComponents(Context context, Glide glide) {
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(new OKHttpUtils(context).getHttpClient()));
}
}
OkHttpStreamFetcher.class
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* Fetches an {@link InputStream} using the okhttp library.
*/
public class OkHttpStreamFetcher implements DataFetcher<InputStream> {
private final OkHttpClient client;
private final GlideUrl url;
private InputStream stream;
private ResponseBody responseBody;
public OkHttpStreamFetcher(OkHttpClient client, GlideUrl url) {
this.client = client;
this.url = url;
}
@Override
public InputStream loadData(Priority priority) throws Exception {
Request.Builder requestBuilder = new Request.Builder()
.url(url.toStringUrl());
for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
String key = headerEntry.getKey();
requestBuilder.addHeader(key, headerEntry.getValue());
}
Request request = requestBuilder.build();
Response response = client.newCall(request).execute();
responseBody = response.body();
if (!response.isSuccessful()) {
throw new IOException("Request failed with code: " + response.code());
}
long contentLength = responseBody.contentLength();
stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
return stream;
}
@Override
public void cleanup() {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Ignored
}
}
if (responseBody != null) {
responseBody.close();
}
}
@Override
public String getId() {
return url.getCacheKey();
}
@Override
public void cancel() {
// TODO: call cancel on the client when this method is called on a background thread. See #257
}
}
OkHttpUrlLoader.class
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
/**
* Fetches an {@link InputStream} using the okhttp library.
*/
public class OkHttpStreamFetcher implements DataFetcher<InputStream> {
private final OkHttpClient client;
private final GlideUrl url;
private InputStream stream;
private ResponseBody responseBody;
public OkHttpStreamFetcher(OkHttpClient client, GlideUrl url) {
this.client = client;
this.url = url;
}
@Override
public InputStream loadData(Priority priority) throws Exception {
Request.Builder requestBuilder = new Request.Builder()
.url(url.toStringUrl());
for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
String key = headerEntry.getKey();
requestBuilder.addHeader(key, headerEntry.getValue());
}
Request request = requestBuilder.build();
Response response = client.newCall(request).execute();
responseBody = response.body();
if (!response.isSuccessful()) {
throw new IOException("Request failed with code: " + response.code());
}
long contentLength = responseBody.contentLength();
stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
return stream;
}
@Override
public void cleanup() {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Ignored
}
}
if (responseBody != null) {
responseBody.close();
}
}
@Override
public String getId() {
return url.getCacheKey();
}
@Override
public void cancel() {
// TODO: call cancel on the client when this method is called on a background thread. See #257
}
}
3.添加信任自定義證書(shū)工具類蕾久,下面貼出重要方法
public SSLSocketFactory getSSLSocketFactory(X509TrustManager trustManager) {
SSLSocketFactory sslSocketFactory;
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
return sslSocketFactory;
}
private X509TrustManager getX509TrustManager()
throws GeneralSecurityException {
InputStream inputStream = null;
try {
inputStream = mContext.getAssets().open("server.cer");
}catch (IOException e){
e.printStackTrace();
}
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(inputStream);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
// Put the certificates a key store.
char[] password = "test".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
4.builde.gradule 添加依賴 com.github.bumptech.glide:glide:3.7.0,在Androidmanifest中配置GlideModule(用自定義的替換默認(rèn)的)
compile 'com.github.bumptech.glide:glide:3.7.0'
<meta-data
android:name="com.test.http.OkHttpGlideModule"
android:value="GlideModule"/>
5.加載圖片(加載失敗時(shí)重試)
Glide.with(PhotoActivity.this)
.load(url)
.asBitmap()
.listener(new RequestListener<String, Bitmap>() {
@Override
public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
//加載失敗時(shí)重試
handler.postDelayed(new Runnable() {
@Override
public void run() {
loadPhoto(photoView,url);
}
}, 5000);
return false;
}
@Override
public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
return false;
}
})
.into(photoView);
最近項(xiàng)目中正好遇到這個(gè)問(wèn)題拌夏,記錄下來(lái)跟大家分享僧著,歡迎交流履因!