资讯专栏INFORMATION COLUMN

高性能的OkHttp

Ocean / 2426人阅读

摘要:响应会被缓存写入指定的文件夹,如果缓存大小已经超过了文件夹的指定大小,会根据规则来进行筛选。除了能够允许开发者监测数据库以及视图层级之外,还能辅助监测所有的来自的网络请求与响应。

原文地址,这里

OkHttp 是笔者在为为 Khan Academy开发这个 Android app时候的必用库之一。OkHttp库本身已经提供了非常优秀的功能配置,但是下面是我们在实践中总结出来的一些能够有效增加资源利用率的步骤:

使用文件系统级别的响应缓存

默认情况下,OkHttp并没有将包含Cache-Control头部文件的响应进行缓存。因此你的客户端可能会浪费时间与带宽去重复请求相同的资源,而不是简单地读取初次请求时候的缓存副本。为了保证基于文件系统的响应缓存,应该配置一个com.squareup.okhttp.Cache实例并且把它传递给OkHttpClientsetCache方法。在初始化该Cache时,需要指定一个File对象来指代文件目录以及最大的缓存容量。响应会被缓存写入指定的文件夹,如果缓存大小已经超过了文件夹的指定大小,会根据LRU规则来进行筛选。下面是笔者的具体实践:

// 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));
}

其中,我们建议的HTTP_RESPONSE_DISK_CACHE_MAX_SIZE 值为10 * 1024 * 1024, 或者 10 MB。

使用Stetho

Stetho 是来自于Facebook的一个很有用的辅助库,能够允许开发者使用 Chrome Developer Tools 来监测Android应用。除了能够允许开发者监测SQLite数据库以及视图层级之外,Stetho还能辅助监测所有的来自OkHttp的网络请求与响应。

这样的自检方法能够保证服务器返回恰当的带有缓存控制的响应,同时还能监测当缓存资源存在时是否确定没有请求被发出。如果要使用Stetho,只需要简单地来添加一个StethoInterceptor实例到网络拦截器中:

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

接下来,在应用运行之后,打开Chrome并且跳转到chrome://inspect界面,既可以看到上述画面。

与Picasso以及Retrofit混合使用

笔者是直接使用了Picasso进行网络图片的加载,以及使用Retrofit来简化请求构造以及响应解码。默认情况下,这两个库是使用了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有一个很类似的工厂方法。在应用中,图片往往是常用的大型资源之一,Picasso本身维护了一个基于LRU规则的缓存系统,是直接在内存中的缓存。

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);
定制一个User Agent拦截器

对于由客户端提供的包含在User-Agent头文件中的详细的本机信息是往往用来日志记录与分析的重要来源。默认情况下,OkHttp中自带的User-Agent属性会说明OkHttp的版本。如果需要定制自己的User-Agent信息,可以通过创建一个拦截器并且替换以下这些值:

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的值时,我们使用了如下信息:

Android的版本信息

Build.MODEL, 或者用户可见的终端产品名

Build.BRAND

Build.VERSION.SDK_INT

BuildConfig.APPLICATION_ID

BuildConfig.VERSION_NAME

BuildConfig.VERSION_CODE

最后三个值是Gradle文件中包含的版本信息。如果你是使用的WebView,则可以直接在WebView中进行构造:

WebSettings settings = webView.getSettings();
settings.setUserAgentString(userAgentHeaderValue);
明确合理的超时时间

Picasso specifies:

A connect timeout of 15 seconds.

A read timeout of 20 seconds.

A write timeout of 20 seconds.

Whereas Retrofit specifies:

A connect timeout of 15 seconds.

A read timeout of 20 seconds.

No write timeout.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/12483.html

相关文章

  • Xutils, OKhttp, Volley, Retrofit对比

    摘要:就是使用进行操作。不过设计的初衷本身也就是为频繁的数据量小的网络请求而生。是公司出品的默认基于封装的一套网络请求框架,是目前流行的一套设计的风格,并不是标准。所以这两个库相比,更有优势,在能掌握两个框架的前提下该优先使用。Xutils这个框架非常全面,可以进行网络请求,可以进行图片加载处理,可以数据储存,还可以对view进行注解,使用这个框架非常方便,但是缺点也是非常明显的,使用这个项目,会...

    Alliot 评论0 收藏0
  • 2019最新Android面试题

    摘要:若拦截事件返回为,表示拦截,事件不会向下层的或者传递,表示不拦截,继续分发事件。五注册反注册未成对使用引起的内存泄漏。七集合对象没有及时清理引起的内存泄漏。 原文链接:https://blog.csdn.net/wen_hah... 版权声明:本文为博主原创文章,转载请附上博文链接! 前言 金三银四到来了,找工作的好时候到了,小伙伴们是不是都在忙着找工作呢,小弟前一阵也是忙着在找工作,...

    plus2047 评论0 收藏0
  • OkHttp3源码详解(五) okhttp连接池复用机制

    摘要:长久不关闭会造成过多的僵尸连接和泄露连接出现。连接池的使用连接池的使用连接池的类位于。我们的主旨是了解到如何在时间内复用,并且有效的对其进行回收清理操作。其成员变量代码片线程池,用来检测闲置并对其进行清理。则直接复用缓存列表中的作为的连接。1、概述 提高网络性能优化,很重要的一点就是降低延迟和提升响应速度。 通常我们在浏览器中发起请求的时候header部分往往是这样的 keep-alive...

    番茄西红柿 评论0 收藏0
  • Android实战之你应该使用哪个网络库?

    摘要:网络库对比获得了巨大的社区的支持,以至于最终是将它作为了默认的,并且会在之后弃用。事实上,从开始,所有的网络操作都必须强制在单独的线程中进行。到现在,我发现应该把这些网络库的关系表述在一张图中。 本篇为翻译文章 原文地址这里 如果正在学习Android,建议可以参考笔者的我的编程之路——知识管理与知识体系 [TOC] 前言 目前基本上每个应用都会使用HTTP/HTTPS协议来作为主要的...

    WelliJhon 评论0 收藏0
  • Android 网络优化,使用 HTTPDNS 优化 DNS,从原理到 OkHttp 集成

    摘要:使用时,只需要在中,调用方法来注册此拦截器即可。在拦截器中,使用这个帮助类,通过将转为对应的。服务端根据请求,选择合适的算法,下发公钥证书和随机数。客户端对服务端证书,进行校验,并发送随机数信息,该信息使用公钥加密。 showImg(https://segmentfault.com/img/remote/1460000018642192); 一、前言 谈到优化,首先第一步,肯定是把一个...

    livem 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<