Android网络库之Okio源码分析

今天来扒一扒Square公司的IO流的库Okio,现在越来越多Android项目都在使用Square公司的网络开源全家桶,即 Okio + OkHttp + Retrofit。这三个库的层级是从下网上来看,Okio用来处理IO流,OkHttp用来实现Http协议,Retrofit用来做Android端的网络使用接口,关于Retrofit,之前写过源码分析。但是相对于RetrofitOkHttp,Okio就比较低调,因为它偏底层,大部分同学对它可能不太熟悉,我们今天就来看看这个幕后英雄吧。

Square功德无量,著名的JakeWharton大神之前就一直在这家公司(据说今年7月份离职了)。

一 为什么需要Okio

首先我们需要强调Okio是一个Java库,所以它的底层流肯定都是JavaIO中定义的基础流。基础流指的是Java中对于从不同数据来源抽象的流,比如是FileInputStream ByteInputStream PipedInputStream等,Okio只是优化了Java IO库中对于基础流包装的API

1.1 更加简洁

我们经常说JavaIO库是JDK设计的比较精妙的一个API,由于使用了装饰者模式,大大减少了类的数目。然而即便如此,大家使用时仍然感觉比较麻烦,比如我们想要从一个文件中读取出来一个int数据,我们至少要创建如下几个对象:

FileInputStream //用于打开文件流
BufferedInputStream //对FileInputStream做装饰,添加buffer功能,避免频繁IO
DataInputStream //用于将字节流转化成Java基本类型

此时,通过DataInputStream.readInt()就可以读出来一个int了。但是机智的你已经发现了,我们需要和至少三个跟输入相关的类打交道,而Okio把这些都做了集中处理,你可能只需要一个类就可以很方便的进行以上的各种操作了。

1.2 提高性能

首先okio内部用一个Segment对象来描述内存数据,Segment对象中就有byte[]作为数据的载体。对于Segment来说,Okio不是每次都去创建,而且通过一个对象池来做复用,这样就可以减少对象创建,销毁代价,实际上也可以减少byte[]数组zero-fill的代价。关于Segment,我们会在第四章专门进行介绍。

其次,Okio中多个流之间的数据是可以共享的,而不需要进行内存拷贝。我们举个栗子,如果我使用Java IO从一个文件中读取数据,写入另外一个文件中,代码大致如下:

 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("in.file")));
 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File("out.file")));
 byte[] bytes = new byte[2048];
 int count;
 while ((count = bufferedInputStream.read(bytes)) != -1) {
      bufferedOutputStream.write(bytes,0,count);
 }
bufferedOutputStream.flush();

BufferedInputStream内部有个缓存,每次read的时候,先看看自己缓存中是否满足读取方的需要,如果满足,直接从内部缓存中做内存copy到读取方传入的byte数组(步骤一);如果不满足,调用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值