没有合适的资源?快使用搜索试试~ 我知道了~
android开发进阶之NIO非阻塞包
4星 · 超过85%的资源 需积分: 10 9 下载量 198 浏览量
2012-08-14
23:11:02
上传
评论
收藏 600KB PDF 举报
温馨提示
试读
17页
关于在android使用java提供的NIO非阻塞包,进行开发高并发性程序。
资源推荐
资源详情
资源评论
1
Android 开发进阶之 NIO 非阻塞包(一)
(注:本文整理自 Android 开发网)
对于 Android 的网络通讯性能的提高,我们可以使用 Java 上高性能
的 NIO (New I/O) 技术进行处理,NIO 是从 JDK 1.4 开始引入的,NIO
的 N 我们可以理解为 Noblocking 即非阻塞的意思,相对应传统的
I/O,比如 Socket 的 accpet()、read()这些方法而言都是阻塞的。
NIO 主要使用了 Channel 和 Selector 来实现,Java 的 Selector 类
似 Winsock 的 Select 模式,是一种基于事件驱动的,整个处理方法使
用了轮询的状态机,如果你过去开发过 Symbian 应用的话这种方式有
点像活动对象,好处就是单线程更节省系统开销,NIO 的好处可以很好
的处理并发,对于 Android 网游开发来说比较关键,对于多点 Socket
连接而言使用 NIO 可以大大减少线程使用,降低了线程死锁的概率,
毕竟手机游戏有 UI 线程,音乐线程,网络线程,管理的难度可想而
知,同时 I/O 这种低速设备将影响游戏的体验。
NIO 作为一种中高负载的 I/O 模型,相对于传统的 BIO (Blocking
I/O)来说有了很大的提高,处理并发不用太多的线程,省去了创建销
毁的时间,如果线程过多调度是问题,同时很多线程可能处于空闲状
态,大大浪费了 CPU 时间,同时过多的线程可能是性能大幅下降,一
般的解决方案中可能使用线程池来管理调度但这种方法治标不治本。
使用 NIO 可以使并发的效率大大提高。当然 NIO 和 JDK 7 中的 AIO 还
存在一些区别,AIO 作为一种更新的当然这是对于 Java 而言,如果你
开发过 Winsock 服务器,那么 IOCP 这样的 I/O 完成端口可以解决更高
级的负载,当然了今天 Android123 主要给大家讲解下为什么使用 NIO
在 Android 中有哪些用处。
NIO 我们分为几个类型分别描述,作为 Java 的特性之一,我们需要
了解一些新的概念,比如 ByteBuffer 类,Channel,SocketChannel,
ServerSocketChannel ,Selector 和 SelectionKey 。有关具体的使
用,Android 开发网将在明天详细讲解。网友可以在 Android SDK 文档
中看下 java.nio 和 java.nio.channels 两个包了解。
2
Android 开发进阶之 NIO 非阻塞包(二)
有关 Android NIO 我 们 主 要 分 为 三 大 类 , ByteBuffer 、
FileChannel 和 SocketChannel。由于篇幅原因今天 Android123 只对
前两个做说明。NIO 和传统的 I/O 比较大的区别在于传输方式非阻塞,
一种基于事件驱动的模式,将会使方法执行完后立即返回,传统 I/O
主要使用了流 Stream 的方式,而在 New I/O 中,使用了字节缓存
ByteBuffer 来承载数据。
ByteBuffer 位于 java.nio 包中,目前提供了 Java 基本类型中除
Boolean 外其他类型的缓冲类型,比如 ByteBuffer、DoubleBuffer、
FloatBuffer、IntBuffer、LongBuffer 和 ShortBuffer 。同时还提
供了一种更特殊的映射字节缓冲类型 MappedByteBuffer。在传统 IO 的
输入输出流中,InputStream 中只提供了字节型或字节数组的访问对应
NIO 就是 ByteBuffer,但是处理传统的 DataInputStream 的 int 等类
型,就是 IntBuffer,但是缓冲类型并没有提供 UTF 这样的类型处理,
所以我们仍然需要使用 ByteBuffer 处理字符串,但是 NIO 提供了一个
封装的类在 java.nio.charset 包中,通过字符的编码 CharsetEncoder
和解码 CharsetDecoder 类来处理字符串,同时这些类可以方便转换编
码比如 GBK 或 UTF 等等。
一、ByteBuffer 类
1) 实例化
直 接 使 用 ByteBuffer 类 的 静 态 方 法 static ByteBuffer
allocate(int capacity) 或 static ByteBuffer allocateDirect(int
capacity) 这两个方法来分配内存空间,两种方法的区别主要是后者
更适用于繁复分配的字节数组。而 put(ByteBuffer src) 可以从另一
个 ByteBuffer 中构造,也可以通过 wrap 方法从 byte[]中构造,具体
参考下面的类型转化内容。
2) 类型转化
3
ByteBuffer 可以很好的和字节数组 byte[]转换类型,通过执行
ByteBuffer 类的 final byte[] array() 方法就可以将 ByteBuffer
转为 byte[]。从 byte[]来构造 ByteBuffer 可以使用 wrap 方法,目前
Android 或 者 说 Java 提 供 了 两 种 重 写 方 法 , 比 如 为 static
ByteBuffer wrap(byte[] array) 和 static ByteBuffer
wrap(byte[] array, int start, int len) ,第二个重载方法中第
二个参数为从 array 这个字节数组的起初位置,第三个参数为 array
这个字节数组的长度。
3) 往 ByteBuffer 中添加元素
目前 ByteBuffer 提供了多种 put 重写类型来添加,比如 put(byte
b) 、putChar(char value) 、putFloat(float value) 等等,需要注
意的是,按照 Java 的类型长度,一个 byte 占 1 字节,一个 char 类型
是 2 字节,一个 float 或 int 是 4 字节,一个 long 则为 8 字节,和传
统的 C++有些区别。所以内部的相关位置也会发生变化,同时每种方法
还提供了定位的方法比如 ByteBuffer put(int index, byte b)
4) 从 ByteBuffer 中获取元素
同上面的添加想法,各种 put 被换成了 get,比如 byte get() 、
float getFloat() ,当然了还提供了一种定位的方式,比如 double
getDouble(int index)
5) ByteBuffer 中字节顺序
对于 Java 来说默认使用了 BIG_ENDIAN 方式存储,和 C 正好相反
的,通过 final ByteOrder order() 返回当前的字节顺序。
final ByteBuffer order(ByteOrder byteOrder) 设 置 字 节 顺 序 ,
ByteOrder 类的值有两个定义,比如 LITTLE_ENDIAN、BIG_ENDIAN,如
果使用当前平台则为 ByteOrder.nativeOrder()在 Android 中则为
BIG_ENDIAN,当然如果设置为 order(null) 则使用 LITTLE_ENDIAN。
二、FileChannel 类
4
在 NIO 中除了 Socket 外 , 还 提 供 了 File 设 备 的 通 道 类 ,
FileChannel 位于 java.nio.channels.FileChannel 包中,在 Android
SDK 文 档 中 我 们 可 以 方 便 的 找 到 , 对 于 文 件 复 制 我 们 可 以 使 用
ByteBuffer 方式作为缓冲,比如
String infile = "/sdcard/cwj.dat";
String outfile = "/sdcard/android123-test.dat";
FileInputStream fin = new FileInputStream( infile );
FileOutputStream fout = new FileOutputStream( outfile );
FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel();
ByteBuffer buffer = ByteBuffer.allocate( 1024 ); // 分配
1KB 作为缓冲区
while (true) {
buffer.clear(); //每次使用必须置空缓冲区
int r = fcin.read( buffer );
if (r==-1) {
break;
}
buffer.flip(); //写入前使用 flip 这个方法
fcout.write( buffer );
}
flip 和 clear 这两个方法是 java.nio.Buffer 包中,ByteBuffer
的父类是从 Buffer 类继承而来的,这点 Android123 要提醒大家看
Android SDK 文档时注意 Inherited Methods,而 JDK 的文档就比较直
接了,同时复制文件使用 FileChannel 的 transferTo(long position,
long count, WritableByteChannel target) 这个方法可以快速的复
制文件,无需自己管理 ByteBuffer 缓冲区。明天 Android 开发网介绍
NIO 主要的 Socket 相关的内容。
剩余16页未读,继续阅读
资源评论
- slin_h2013-04-07都是用阻塞式的, 这个写法还不懂,看看
zss503
- 粉丝: 1
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功