Picasso加载https的图片加载不出来的解决方案
最近项目中有需求–要显示https链接的图片,但是配置好路径后原生的Picasso死活没法加载出图片,最后在网上找到了如下的解决办法
确认依赖
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.picasso:picasso:2.5.2'
-
自定义类
ImageDownLoader
实现com.squareup.picasso.Downloader
代码如下:package china.test.helper; import android.net.Uri; import com.squareup.picasso.Downloader; import com.squareup.picasso.NetworkPolicy; import java.io.IOException; import okhttp3.Cache; import okhttp3.CacheControl; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import okhttp3.Request; /** * Created by benchengzhou on 2017/11/14 13:52 . * 作者邮箱: [email protected] * 功能描述: 重写picasso的下载器,修改使用okhttp3作为下载 * 类 名: ImageDownLoader * 备 注: */ public class ImageDownLoader implements Downloader { /* OkHttpClient client = new OkHttpClient.Builder() .protocols(Collections.singletonList(Protocol.HTTP_1_1)) .build();*/ private OkHttpClient client= null; public ImageDownLoader(OkHttpClient okHttpClient) { this.client = okHttpClient; } @Override public Response load(Uri uri, int networkPolicy) throws IOException { CacheControl cacheControl = null; if (networkPolicy != 0) { if (NetworkPolicy.isOfflineOnly(networkPolicy)) { cacheControl = CacheControl.FORCE_CACHE; } else { CacheControl.Builder builder = new CacheControl.Builder(); if (!NetworkPolicy.shouldReadFromDiskCache(networkPolicy)) { builder.noCache(); } if (!NetworkPolicy.shouldWriteToDiskCache(networkPolicy)) { builder.noStore(); } cacheControl = builder.build(); } } Request.Builder builder = new Request.Builder().url(uri.toString()); if (cacheControl != null) { builder.cacheControl(cacheControl); } okhttp3.Response response = client.newCall(builder.build()).execute(); int responseCode = response.code(); if (responseCode >= 300) { response.body().close(); throw new ResponseException(responseCode + " " + response.message(), networkPolicy, responseCode); } boolean fromCache = response.cacheResponse() != null; ResponseBody responseBody = response.body(); return new Response(responseBody.byteStream(), fromCache, responseBody.contentLength()); } @Override public void shutdown() { Cache cache = client.cache(); if (cache != null) { try { cache.close(); } catch (IOException ignored) { } } } }
2.解决 Picasso 初始化配置使用我们自定义的 Downloader ,在application中添加初始化配置代码
/** * 初始化picasso使用okhttp作为网络请求框架 */ private void initPicasso() { Picasso.setSingletonInstance(new Picasso.Builder(this). downloader(new ImageDownLoader(getSOkHttpClient())).loggingEnabled(true) .build()); }
3.
getSOkHttpClient()
中的代码/** * 创建全局OkHttpClient对象 * <p> * OkHttpClient 用于管理所有的请求,内部支持并发, * 所以我们不必每次请求都创建一个 OkHttpClient 对象,这是非常耗费资源的。接下来就是创建一个 Request 对象了 * * @return */ public static OkHttpClient getSOkHttpClient() { //创建okhttp的请求对象 参考地址 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html if (sOkHttpClient == null) { sOkHttpClient = new OkHttpClient.Builder() .readTimeout(20000, TimeUnit.SECONDS)//设置读取超时时间 .writeTimeout(20000, TimeUnit.SECONDS)//设置写的超时时间 .connectTimeout(20000, TimeUnit.SECONDS)//设置连接超时时间 .sslSocketFactory(createSSLSocketFactory()) //添加信任所有证书 .hostnameVerifier(new HostnameVerifier() { //信任规则全部信任 @Override public boolean verify(String hostname, SSLSession session) { return true; } }) .build(); } return sOkHttpClient; }
3.1这里的 OkHttpClient 对象全局使用一个,同时可以作为项目的okhttp的网络请求的OkHttpClient的封装,我的项目里面的网络请求也是使用的这一个
其中
.sslSocketFactory(createSSLSocketFactory()) //添加信任所有证书 .hostnameVerifier(new HostnameVerifier() { //信任规则全部信任 @Override public boolean verify(String hostname, SSLSession session) { return true; } })
是增加的对https协议的支持
4.
createSSLSocketFactory
方法中增加 信任规则/** * 测试环境https添加全部信任 * okhttp的配置 * * @return */ private static SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory ssfFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom()); ssfFactory = sc.getSocketFactory(); } catch (Exception e) { } return ssfFactory; }
5.创建一个行的文件 TrustAllCerts.java 配置对应的信任规则
package china.test.helper; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /** * Created by benchengzhou on 2017/11/13 10:09 . * 作者邮箱: [email protected] * 功能描述: 测试环境添加https全部信任 * 类 名: TrustAllCerts * 备 注: */ public class TrustAllCerts implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];} }
OK!剩下的就是慢慢的使用吧go
好了问题解决了放过来看一下原理:
查阅文档我们发现OKhttp是可以对下载器进行设置的,也就是提供给我们了指定或自定义下载器的可能,文档有这句话
downloader(Downloader downloader) :
容许使用自定义的下载器,可以用okhttp或者volley,必须实现Downloader接口。
这是文章的链接 http://blog.csdn.net/u011228356/article/details/45026441 有兴趣的同学可以研究一下,这里不做深究
正是因为如此,我们可以如下实现
picassoBuilder.downloader(new ImageDownLoader(client));
指定使用OKhttp作为网络下载器,故而问题转接成为只要可以实现okhttp可以实现 https的请求我们的Picasso就可以完成加载https的图片了
如果想要看OKhttp实现https请求请移步我的博客
- 当然我现在项目的build配置如下,:
compile ‘com.squareup.okhttp3:okhttp:3.5.0’
compile ‘com.squareup.picasso:picasso:2.3.2’
参考链接: Picasso加载https的图片加载不出来的解决方案
和http://blog.csdn.net/qq_15037349/article/details/54089249
再此感谢