Okhttp的高效使用方式

OkHttp 是一个很重要的开源库。它的默认配置已经提供了很好的效果,我们还是采取了一些措施提高 OkHttp 的可用性和自我检查能力:

1. 在文件系统中开启响应缓存

有些响应消息通过包含Cache-Control HTTP首部字段允许缓存,但是默认情况下,OkHttp 并不会缓存这些响应消息。因此你的客户端可能会因为不断请求相同的资源而浪费时间和带宽,而不是简单地读取一下首次响应消息的缓存副本。

为了在文件系统中开启响应缓存,需要配置一个 com.squareup.okhttp.Cache 实例,然后把它传递 给 OkHttpClient 实例的 setCache 方法。你必须用一个表示目录的 File 对象和最大字节数来实例化 Cache 对象。那些 能够缓存的响应消息会被写在指定的目录中。如果已缓存的响应消息导致目录内容超过了指定的大小,响应消息会按照最近最少使用( LRU Policy )的策略被移除。

正如 Jesse Wilson 所建议的 ,我们将响应消息缓存在 context.getCacheDir() 的子文件夹中:

final @Nullable File baseDir = context.getCacheDir();

if (baseDir != null) {

final File cacheDir = new File(baseDir, "HttpResponseCache");

okHttpClient.setCache(new Cache(cacheDir, 10*1024*1024));

}

2. 集成 Stetho

Stetho 是一个 Facebook 出品的超赞的开源库,它可以让你用 Chrome 的功能—— 开发者工具 来检查调试Android 应用。

Stetho 不仅能够检查应用的 SQLite 数据库和视图层次,还可以检查 OkHttp 的每一条请求和响应消息:

这种自我检查方式(Introspection)有效地确保了服务器返回允许缓存资源的 HTTP 首部时,且核缓存资源存在时,不再发出任何请求。

开启 Stetho,

public class MyApplication extends Application {

public void onCreate() {

super.onCreate();

Stetho.initializeWithDefaults(this);

}

}

添加一个 StethoInterceptor 实例到网络拦截器(Network Interceptor)的列表中去:

OkHttpClient client = new OkHttpClient();

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

or:

new OkHttpClient.Builder()

.addNetworkInterceptor(new StethoInterceptor())

.build();

应用运行完毕之后,打开 Chrome 然后跳转到 chrome://inspect。设备、应用以及应用标识符信息会被陈列出来。直接点击“inspect”链接就可以打开开发者工具,然后切换到 Network 标签开始监测 OkHttp 发出的请求。

3. 使用 Picasso 和 Retrofit

可能和我们一样,你使用 Picasso 来加载网络图片,或者使用  Retrofit 来简化网络请求和解析响应消息。在默认情况下,如果你没有显式地指定一个 OkHttpClient,这些开源库会隐式地创建它们自己 的 OkHttpClient 实例以供内部使用。以下代码来自于 Picasso 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;

}

Retrofit 也有类似的工厂方法用来创建它自己的 OkHttpClient,在OkClient类中。

图片是应用中需要加载的最大的资源之一。Picasso 是严格地按照 LRU 策略在内存中维护它的图片缓存。如果客户端尝试用 Picasso 加载一张图片,并且 Picasso 没有在内存缓存中找到该图片,那么它会委托内部的 OkHttpClient 实例来加载该图片。在默认情况下,由于前面的 defaultOkHttpClient 方法没有在文件系统中配置响应缓存,该实例会一直从服务器加载图片。

自定义一个 OkHttpClient 实例,将从文件系统返回一个已缓存的响应消息这种情况考虑在内。没有一张图片直接从服务器加载。这在应用第一次加载时是尤为重要的。在这个时候,Picasso 的内存中的缓存是 “冷” 的,它会频繁地委托 OkHttpClient 实例去加载图片。

这就需要构建一个用你的 OkHttpClient 配置的 Picasso 实例。如果你在代码中使用 Picasso.with(context).load(...) 来加载图片,你所使用的 Picasso 单例对象,是在with 方法中用自己 的 OkHttpClient 延迟加载和配置的。因此我们必须在第一次调用 with方法之前指定自己的 Picasso 实例作为单例对象。

简单地把 OkHttpClient 实例包装到一个 OkHttpDownloader 对象中,然后传递给Picasso.Builder 实例的 downloader 方法:

final Picasso picasso = new Picasso.Builder(context)

.downloader(new OkHttpDownloader(okHttpClient))

.build();

//客户端应该在任何需要的时候来创建这个实例

//以防万一,替换掉那个单例对象

Picasso.setSingletonInstance(picasso);

在 Retrofit 1.9.x 中,通过 RestAdapter 使用你的 OkHttpClient 实例,把 OkHttpClient实例包装到一个 OkClient 实例 中,然后传递给 RestAdapter.Builder 实例的 setClient方法:

restAdapterBuilder.setClient(new OkClient(httpClient));

在 Retrofit 2.0 中,直接把 OkHttpClient 实例传递给 Retrofit.Builder 实例的 client即可。

4. 设置用户代理拦截器(User-Agent Interceptor)

当客户端在每一次请求中都提供一个详细的 User-Agent 头部信息时,日志文件和分析数据提供了很有用的信息。默认情况下,OkHttp 的 User-Agent 值仅仅只有它的版本号。要设定你自己的 User-Agent,创建一个拦截器(Interceptor)然后替换掉默认值,参考 StackOverflow 上的建议 :

public final class UserAgentInterceptor implements Interceptor {

private static final String USER_AGENT_HEADER_NAME = "User-Agent";

private final String userAgentHeaderValue;

public UserAgentInterceptor(String userAgentHeaderValue) {

this.userAgentHeaderValue = Preconditions.checkNotNull(userAgentHeaderValue);

}

@Override

public Response intercept(Chain chain) throws IOException {

final Request originalRequest = chain.request();

final Request requestWithUserAgent = originalRequest.newBuilder()

.removeHeader(USER_AGENT_HEADER_NAME)

.addHeader(USER_AGENT_HEADER_NAME, userAgentHeaderValue)

.build();

return chain.proceed(requestWithUserAgent);

}

}

使用任何你觉得有价值的信息,来创建 User-Agent。

如果你的应用中用到了 WebView,你可以配置使用相同的 User-Agent 值,即之前创建的 UserAgentInterceptor:

WebSettings settings = webView.getSettings();

settings.setUserAgentString(userAgentHeaderValue);

5. 指定合理的超时

在 2.5.0 版本之前,OkHttp 请求默认永不超时。从 2.5.0 版本开始,如果建立了一个连接,或从连接读取下一个字节,或者向连接写入下一个字节,用时超过了10秒,请求就会超时。分别调 用 setConnectTimeout,setReadTimeout 或 setWriteTimeout 方法可以重写那些默认值。

Picasso 和 Retrofit 为它们的默认 OkHttpClient 实例指定不同的超时时长。 默认情况下, Picasso 设定如下:

- 连接超时15秒

- 读取超时20秒

- 写入超时20秒

Retrofit 设定如下:

- 连接超时15秒

- 读取超时20秒

- 写入无超时

用你自己的 OkHttpClient 实例配置好 Picasso 和 Retrofit 之后,就能确保所有请求超时的一致性了。

扫码关注公众账号,分享更多资料。

时间: 2024-10-07 05:21:14

Okhttp的高效使用方式的相关文章

AI重新定义ITSM高效工作方式1

人工智能(AI)正在进入IT服务管理(ITSM),承诺重新定义工作方式.但AI会实现其承诺并真正使ITSM更容易,更有效吗?这就是我们在这个由两部分组成的系列中探讨的内容,即"ITSM中的AI优势".早些时候,我们为人工智能讨论设置了第一部分"AI在ITSM工作中"的讨论阶段.现在,在第二部分"功能和用例"中,我们将介绍基于AI的特定功能和用例场景跨越各种ITSM模块,解释基于AI的模型和功能如何改变IT服务台的工作方式.让我们从AI智能服务台开

AI重新定义ITSM高效工作方式2

在我们上一篇文章中解析了AI在ITSM中聊天机器人场景用例,接下来我们继续了解ITSM中的AI优势.知识管理AI算法和智能服务台仅与其可用知识库一样有效.对我们来说幸运的是,AI还可以帮助建立一个坚固的知识库.我们将讨论两个用例,以了解AI如何为IT服务台中的知识管理做出贡献. 方案1:自动评估解决方案以批准和拒绝它们.对于每个事件或事件类别,可能存在一段时间内使用的多个解决方案和知识库文章.可以训练基于ML的特定模型,以基于历史性能来识别每种解决方案的成功率.这可以通过考虑多种因素来完成,例如

现代物流的高效配送方式

入库和检验 当贴有电子标签的货物运抵配送中心时,入口处的阅读器将自动识读标签,根据读到的信息,管理系统会自动更新存货清单,同时,根据订单的需要,将相应货物发往正确的地点.这一过程将传统的货物验收入库程序大大简化,省去了繁琐的检验.记录.清点等大量需要人力的工作. 整理和补充货物 装有自感应条码扫描枪的运送车自动对货物进行整理,根据计算机管理中心的指示自动将货物运送到正确的位置上,同时将计算机管理中心的存货清单更新,记录下最新的货物位置.存货补充系统将在存货不足指定数量时自动向管理中心发出申请,根

Condition-线程通信更高效的方式

上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇之上,使用Lock如何处理线程通信. 那么引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)

Java线程(九):Condition-线程通信更高效的方式

原文:http://blog.csdn.net/ghsau/article/details/7481142 接近一周没更新<Java线程>专栏了,主要是这周工作上比较忙,生活上也比较忙,呵呵,进入正题,上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇之上,使用Lock如何处理线程通信. 那么引入本篇的主角,Condition,Condition

高效地配置okhttp

原文链接 : Effective OkHttp 原文作者 : Michael Parker 译文出自 : 开发技术前线 www.devtf.cn.本译文已授权开发者头条(链接:http://toutiao.io/download)享有独家转载权,未经允许,不得转载! 译者 : Damonzh 校对者: desmond1121 状态 : 完成 当我为可汗学院开发Android app的时候,OkHttp是一个十分有用的第三方库.虽然它的默认设置已经提供了很大的便利,但我们还是采取了以下的步骤使Ok

Netty源码学习——Included transports(传输方式)

Transport API的核心: Channel接口 类图表示Channel含有Pipeline和Config接口,pipeline上一节有所介绍. Channel是线程安全的,这表示在多线环境下操作同一个Channel,不会有数据问题. final Channel channel = null; final ByteBuf buf = Unpooled.copiedBuffer("your data", CharsetUtil.UTF_8); // #1 Runnable writ

数据导入HBase最常用的三种方式及实践分析

数据导入HBase最常用的三种方式及实践分析         摘要:要使用Hadoop,需要将现有的各种类型的数据库或数据文件中的数据导入HBase.一般而言,有三种常见方式:使用HBase的API中的Put方法,使用HBase 的bulk load工具和使用定制的MapReduce Job方式.本文均有详细描述. [编者按]要使用Hadoop,数据合并至关重要,HBase应用甚广.一般而言,需要 针对不同情景模式将现有的各种类型的数据库或数据文件中的数据转入至HBase 中.常见方式为:使用H

七个高效的文本编辑习惯(以Vim为例)

七个高效的文本编辑习惯 如果你花很多时间输入纯文本.写程序或HTML,那么通过高效地使用一个好的编辑器,你可以节省大部分时间.本文将提供指导和提示,让你更迅速地做这些工作,并且少犯错误. 本文用开源文本编辑器Vim(Vi IMproved)来演示如何高效编辑,本文方法同样适用于其他的编辑器.选择合适的编辑器,实际上是进行高效编辑的第一步.我们避免去讨论哪个编辑器最适合你,因为这个话题将占用太多篇幅.如果你不知道选用那个编辑器,或者你对目前使用的编辑器不满意,那就试试Vim:你将不会失望. 第1部