android-Picasso请求https加载网络图片不能显示的解决方案

Picasso加载https的图片加载不出来的解决方案

  • 最近项目中有需求–要显示https链接的图片,但是配置好路径后原生的Picasso死活没法加载出图片,最后在网上找到了如下的解决办法

  • 确认依赖

    • compile 'com.squareup.okhttp3:okhttp:3.9.0'
    • compile 'com.squareup.picasso:picasso:2.5.2'
    1. 自定义类 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

再此感谢

猜你喜欢

转载自blog.csdn.net/bencheng06/article/details/78520923