如何高效的使用Okhttp

 我来答
就烦条0o
2016-10-23 · 知道合伙人软件行家
就烦条0o
知道合伙人软件行家
采纳数:33315 获赞数:46492
从事多年系统运维,喜欢编写各种小程序和脚本。

向TA提问 私信TA
展开全部
1. 启用文件系统上的响应缓存

默认情况下,Okhttp不支持响应缓存,包括HTTP Cache-Control头允许缓存响应。因此,客户端通过一次又一次的请求相同的资源浪费时间和带宽。而不是简单地读取初始响应后缓存的副本。

要在文件系统中启用响应缓存,需要配置com.squareup.okhttp.Cache实例,并把它传递给你的OkHttpClient实例的setCache方法。你必须初始化缓存与存放目录的文件,并以字节为单位的最大值。

响应返回数据可以写入给定目录文件,如果一个响应的缓存超过了给定的大小。我们可以采取 LRU policy 。

我们可以在 stackoverflow 查看 Jesse Wilson 的回复。我们可以通过context.getCacheDir()在子目录中缓存我们的响应:

// Base directory recommended by http://stackoverflow.com/a/32752861/400717.
// Guard against null, which is possible according to
// https://groups.google.com/d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// http://stackoverflow.com/q/4441849/400717.
final @Nullable File baseDir = context.getCacheDir();
if (baseDir != null) {
final File cacheDir = new File(baseDir, "HttpResponseCache");
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
}

// Base directory recommended by http://stackoverflow.com/a/32752861/400717.
// Guard against null, which is possible according to
// https://groups.google.com/d/msg/android-developers/-694j87eXVU/YYs4b6kextwJ and
// http://stackoverflow.com/q/4441849/400717.
final @NullableFilebaseDir = context.getCacheDir();
if (baseDir != null) {
final FilecacheDir = new File(baseDir, "HttpResponseCache");
okHttpClient.setCache(new Cache(cacheDir, HTTP_RESPONSE_DISK_CACHE_MAX_SIZE));
}

在可汗学院的程序中我们指定 HTTP_RESPONSE_DISK_CACHE_MAX_SIZE as 10 * 1024 * 1024 , or 10 MB的大小

2. 集成Stetho

Stetho 是Facebook的一个可爱的库,可以使用Chrome浏览器的Chrome开发人员工具功能来检查你的Andr oid应用程序。

Stetho除了允许你检查你的应用程序的SQLite数据库,还可以查看View的层次结构。允许你检查由OkHttp发起的每个请求和响应:

这种自省机制是确保服务器返回允许资源缓存的HTTP头是非常有用的,以及验证没有请求时,保证缓存的资源存在。

要想使用Stetho,只需添加一个StethoInterceptor实例的网络拦截器列表:

okHttpClient.networkInterceptors().add(new StethoInterceptor());

okHttpClient.networkInterceptors().add(new StethoInterceptor());

然后,运行应用程序,打开浏览器后,输入chrome://inspect。然后你就会看到应用程序的设备和标识符的列表。然后鼠标右键选择inspect 打开开发者工具,然后打开新的tab,开始监控OkHttp请求。

3. 使用Picasso 和 Retrofit

你可能使用过 Picasso 来加载网络图片,或者使用 Retrofit 来简化发出请求和解码响应。这些第三方库将隐式地创建自己的OkHttpClient供内部使用,如果你不明确指定一个。

Picasso version 2.5.2的OkHttpDownloader类:

private static OkHttpClient defaultOkHttpClient() {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return client;
}

private static OkHttpClientdefaultOkHttpClient() {
OkHttpClientclient = new OkHttpClient();
client.setConnectTimeout(Utils.DEFAULT_CONNECT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setReadTimeout(Utils.DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
client.setWriteTimeout(Utils.DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
return client;
}

Retrofit也有类似的工厂方法来创建自己的OkHttpClient。

图片一般在应用程序中需要加载的比较大的资源。尽管Picasso自己维护它的LRU机制来缓存图片,在内存中严格执行。如果客户端尝试使用Picasso来加载图片。Picasso会找不到其在内存中缓存图像,然后将委托加载该图片到它的内部OkHttpClient实例。并且默认情况下该实例将始终从服务器加载图片资源。

作为defaultOkHttpClient的方法不能与上面提到的文件系统中的响应缓存配置结合起来。

指定你自己的OkHttpClient实例允许返回数据从文件系统缓存响应,图片不会从服务器加载。这是非常重要的在程序第一次启动以后。这个时候Picasso的内存缓存是冷的。所以它会频繁的委托OkHttpClient实例去加载图片。

这就需要构建配置了您Picasso 的OkHttpClient实例,如果你在你的代码中使用

Picasso.with(context).load(...)

Picasso.with(context).load(...)

加载图片,你是用的是Picasso的单例模式。这是通过with方法懒汉模式地实例化并配置自己的OkHttpClient。因此,我们必须使我们自己的Picasso实例在单例之前通过wiht方法调用。

实现这个,可以简单的将OkHttpClient实例封装在OkHttpDownloader中,然后传递给 Picasso.Builder 实例的downloader方法。

final Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();

// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);

final Picassopicasso = new Picasso.Builder(context)
.downloader(new OkHttpDownloader(okHttpClient))
.build();

// The client should inject this instance whenever it is needed, but replace the singleton
// instance just in case.
Picasso.setSingletonInstance(picasso);

在Retrofit中要使用OkHttpClient实例,需要改造1.9.x的一个RestAdapter,需要将OkHttpClient封装OkClient的实例中。然后把它传递给RestAdapter.Builder实例的setClient方法。

restAdapterBuilder.setClient(new OkClient(httpClient));

restAdapterBuilder.setClient(new OkClient(httpClient));

在 Retrofit 2.0中只需要简单的将OkHttpClient传递给Retrofit.Builder实例的client方法。

在可汗学院的APP中我们通过 Dagger 依赖注入来确保我们只有一个OkHttpClient的实例。这种方法同样也适用于Picasso和Retrofit我们提供了一个为OkHttpClient实例提供单例模式的注解示例:

@Provides
@Singleton
public OkHttpClient okHttpClient(final Context context, ...) {
final OkHttpClient okHttpClient = new OkHttpClient();
configureClient(okHttpClient, ...);
return okHttpClient;
}

@Provides
@Singleton
public OkHttpClientokHttpClient(final Contextcontext, ...) {
final OkHttpClientokHttpClient = new OkHttpClient();
configureClient(okHttpClient, ...);
return okHttpClient;
}

OkHttpClient将会通过Dagger的注解创建一个实例提供给我们的Picasso和Retrofit。
Storm代理
2023-07-25 广告
StormProxies是一家可靠的代理服务提供商,提供原生IP(住宅原生IP)和高匿名代理服务。以下是关于StormProxies的原生IP服务的一些信息:1. 住宅原生IP:StormProxies提供的住宅原生IP是指从真实的家庭或企... 点击进入详情页
本回答由Storm代理提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式