原文地址:http://blog.csdn.net/BingHongChaZuoAn/article/details/52228670
关于okhttp3版piccaso的使用,还是有很多坑的,所以本文详解下如何跳过这些坑。
首先引入jar
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.3.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
compile 'com.squareup.picasso:picasso:2.5.2'
}
然后是Picasso的设置
OkHttpClient okHttpClient = OkHttpClientFactory.createClient(this);
Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(okHttpClient)).build();
Picasso.setSingletonInstance(picasso);
看似很简单,其实这里隐藏着几个坑。
首先,Picasso.setSingletonInstance(picasso)只能调用一次,否则会报错。所以你可以写一个单例模式,放进去,每次调用只调用一次,也可以放到application中初始化,我的就是放到application中初始化的。
其次是新版的piccaso自带了okhttp3,为什么还要创建一个okhttpClient放到OkHttp3Downloader中,是因为https的原因,因为一些主机地址是无法访问的,所以我封装了一个okHttpClient放进去,使其可以访问某些https地址。如果你不需要的话,可以直接这么用
Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(new OkHttpClient())).build();
或者
Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(this)).build();
后面这两种方法 picasso就自带了缓存了。如果用第一种的话,需要缓存还要自己去设置okhttpClient的缓存。
看下 OkHttpClientFactory
public class OkHttpClientFactory {
private static OkHttpClient okHttpClient;
private static int DEFAULT_TIME_OUT = 15;
/**
* 缓存大小
*/
private final static int HTTP_RESPONSE_DISK_CACHE_MAX_SIZE = 1 * 1024*1024;
public static OkHttpClient createClient(Context context) {
/*设置缓存*/
File baseDir = context.getCacheDir();
Cache cache = null;
if (baseDir != null) {
File cacheDir = new File(baseDir, "HttpResponseCache");
cache = new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE);
}
okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.HEADERS))
.addInterceptor(new HeaderInterceptor(new HeaderImpl(context)))
.cookieJar(new CookieManger(context))
.connectionPool(new ConnectionPool(10,5,TimeUnit.SECONDS))
.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
.sslSocketFactory(HttpsHelper.getTrustedFactory(context))
.hostnameVerifier(HttpsHelper.getTrustedVerifier())
.cache(cache)
.build();
return okHttpClient;
}
}
这里是自己封装的一个OkhttpClient,里面好多内容,不一一介绍了,重点看缓存。
.cache(cache)
还有一个坑就是,我也遇到了就是没有找到OkHttp3Downloader这个类。好,我把源码贴出来:
/*
* Copyright (C) 2013 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.picasso;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import java.io.File;
import java.io.IOException;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
/** A {@link Downloader} which uses OkHttp to download images. */
public final class OkHttp3Downloader implements Downloader {
private final Call.Factory client;
private final Cache cache;
private boolean sharedClient = true;
/**
* Create new downloader that uses OkHttp. This will install an image cache into your application
* cache directory.
*/
public OkHttp3Downloader(final Context context) {
this(Utils.createDefaultCacheDir(context));
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into the specified
* directory.
*
* @param cacheDir The directory in which the cache should be stored
*/
public OkHttp3Downloader(final File cacheDir) {
this(cacheDir, Utils.calculateDiskCacheSize(cacheDir));
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into your application
* cache directory.
*
* @param maxSize The size limit for the cache.
*/
public OkHttp3Downloader(final Context context, final long maxSize) {
this(Utils.createDefaultCacheDir(context), maxSize);
}
/**
* Create new downloader that uses OkHttp. This will install an image cache into the specified
* directory.
*
* @param cacheDir The directory in which the cache should be stored
* @param maxSize The size limit for the cache.
*/
public OkHttp3Downloader(final File cacheDir, final long maxSize) {
this(new OkHttpClient.Builder().cache(new Cache(cacheDir, maxSize)).build());
sharedClient = false;
}
/**
* Create a new downloader that uses the specified OkHttp instance. A response cache will not be
* automatically configured.
*/
public OkHttp3Downloader(OkHttpClient client) {
this.client = client;
this.cache = client.cache();
}
/** Create a new downloader that uses the specified {@link Call.Factory} instance. */
public OkHttp3Downloader(Call.Factory client) {
this.client = client;
this.cache = null;
}
@VisibleForTesting Cache getCache() {
return ((OkHttpClient) client).cache();
}
@Override public Response load(@NonNull 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 okhttp3.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() {
if (!sharedClient) {
if (cache != null) {
try {
cache.close();
} catch (IOException ignored) {
}
}
}
}
}
注意,引用的时候包名不要改变,不然就找不到某些类了。看到没,OkHttp3Downloader继承的Downloader,其实你可以写一个OkHttp4Downloader,只要继承Downloader就好了。讲一下,这个OkHttp3Downloader不是我写的,我只是拷过来引用下,别误解。
使用的话很简单,例如:
Picasso.with(this).load("http://h.hiphotos.baidu.com/image/pic/item/08f790529822720e23efdb327fcb0a46f31fabd0.jpg")
.placeholder(R.mipmap.ic_launcher)
.resize(300, 500)
.centerCrop()
.into(imageView1);
使用的例子太多了,官网也有,就不介绍了。
好了,踩坑就到这里吧!