okhttp3版 piccaso的使用

原文地址: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);

使用的例子太多了,官网也有,就不介绍了。
好了,踩坑就到这里吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值