成功解决Glide3.7.0加载https图片,显示占位图问题。

平时我们使用Glide加载http网址的图片的时候,图片可以正常加载出来,但是如果服务器端加上了安全认证,当加载自签名的https图片的时候就会报如下错误(证书路径验证异常)。
Trust anchor for certification path not found.
解决方案:
1.在Application的onCreate()方法中调用该方法。
/**
* 忽略https的证书校验
* 避免Glide加载https图片报错:
* javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
*/

    public static void handleSSLHandshake()
    {
        try
        {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager()
            {
                public X509Certificate[] getAcceptedIssuers()
                {
                    return new X509Certificate[0];
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType)
                {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType)
                {
                }
            }};

            SSLContext sc = SSLContext.getInstance("TLS");
            // trustAllCerts信任所有的证书
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
            {
                @Override
                public boolean verify(String hostname, SSLSession session)
                {
                    return true;
                }
            });
        } catch (Exception ignored)
        {
        }
    }

第一种方案本来已经解决了加载问,但是复制项目,更改ApplicationId和包名后又出现之前问题,仍加载不出来https图片了。各种查阅,现给出第二种方案。

2.okhttp我们使用ssl来信任的所有证书,但是glide使用的自己的网络请求来加载的图片,也就是说,想要用glide访问https图片,就必须替换掉glide原始加载图片的方法,使其同样做到信任所有证书。
所以需要修改Glide的OkHttpGlideModule.class OkHttpStreamFetcher.class OkHttpUrlLoader.class这三个类。

OkHttpGlideModule 类以及导入的类:

import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.GlideModule;
import java.io.InputStream;
import okhttp3.OkHttpClient;

/**
 * 

Glide使用okHttp3请求图片

*

* Created by Gwei at 2021/05/14. */ public class OkHttpGlideModule implements GlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { } @Override public void registerComponents(Context context, Glide glide) { OkHttpClient mHttpClient = new OkHttpClient().newBuilder() .sslSocketFactory(SSLSocketClient.getSSLSocketFactory()) .hostnameVerifier(SSLSocketClient.getHostnameVerifier()) .build(); glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(mHttpClient)); } }

OkHttpStreamFetcher类以及导入的类:

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;
/**
 * Note:
 * Author by Gwei,
 * Date on 2021/5/14.
 *  */
	public class OkHttpStreamFetcher implements DataFetcher {
	    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 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) {
            }
        }
        if (responseBody != null) {
            responseBody.close();
        }
    }

    @Override
    public String getId() {
        return url.getCacheKey();
    }

    @Override
    public void cancel() {
    	}
	}

OkHttpUrlLoader类以及导入类:

import android.content.Context;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import java.io.InputStream;
import okhttp3.OkHttpClient;
/**
 * Note:
 * Author by Gwei,
 * Date on 2021/5/14.
 */
 
public class OkHttpUrlLoader implements ModelLoader {

    public static class Factory implements ModelLoaderFactory {
        private static volatile OkHttpClient internalClient;
        private OkHttpClient client;

      private static OkHttpClient getInternalClient() {
            if (internalClient == null) {
                synchronized (Factory.class) {
                    if (internalClient == null) {
                        internalClient = new OkHttpClient();
                    }
                }
            }
            return internalClient;
        }

     public Factory() {
            this(getInternalClient());
        }

      public Factory(OkHttpClient client) {
            this.client = client;
        }

       @Override
        public ModelLoader build(Context context, GenericLoaderFactory factories) {
            return new OkHttpUrlLoader(client);
        }

        @Override
        public void teardown() {
        }
    }

    private final OkHttpClient client;

    public OkHttpUrlLoader(OkHttpClient client) {
        this.client = client;
    }

    @Override
    public DataFetcher getResourceFetcher(GlideUrl model, int width, int height) {
        return new OkHttpStreamFetcher(client, model);
    }
}

最后在在AndroidManifest.xml里面配置
android:name=“com.example.androidtest.https.OkHttpGlideModule”
android:value=“GlideModule” />

即可成功解决bug!!!

你可能感兴趣的:(Android,Glide加载https,android,java)