Reference: http://www.cnblogs.com/cpcpc/archive/2011/06/27/2123009.html
For Android's improved network communication performance, we can use high-performance NIO (New I/O) technology in Java to process, NIO is introduced from JDK 1.4, NiO N We can understand as noblocking is non-blocking meaning, relative to the traditional I/O, For example, the socket Accpet (), read () These methods are blocked.
NiO mainly uses channel and selector to achieve, Java selector similar to the Winsock Select Mode, is an event-driven, the entire processing method using the rotation state machine, If you've developed Symbian applications in the past, it's a bit like an active object, the advantage is that single-threaded more cost-saving, NiO's benefits can be very good processing concurrency, for Android online game development is more critical, Using NIO for multi-point socket connections can greatly reduce thread usage and reduce the probability of thread deadlock, after all, mobile games have UI threads, music threads, network threads, management difficulty imaginable, and I/o this low-speed device will affect the game experience.
NIO, as a medium-to-high load I/O model, has greatly improved relative to the traditional bio (Blocking I/O), processing concurrency without too many threads, eliminating the time to create destruction, and if too many threads are scheduling problems, and a lot of thread may be idle, wasting CPU time , while excessive threads may be a significant drop in performance, a common solution might use a thread pool to manage scheduling but this approach does not cure the problem. Using NIO can make concurrency much more efficient. Of course there are some differences between NIO and the AIO in JDK 7, AIO as an update of course this is for Java, if you have developed a Winsock server, then the I/O completion port such as IOCP can solve the more advanced load, And, of course, today we're going to explain to you why using NiO is useful in Android.
NiO we are divided into several types to describe, as one of the features of Java, we need to understand some new concepts, such as Bytebuffer class, Channel,socketchannel,serversocketchannel, Selector and Selectionkey. For specific use, you can see the Java.nio and Java.nio.channels two packages in the Android SDK documentation.
Android NiO is divided into three major categories, Bytebuffer, FileChannel and Socketchannel. The big difference between NIO and traditional I/O is that the transport is non-blocking, an event-driven pattern that will return the method as soon as it is executed, the traditional I/O uses the stream stream, and in new I/O, the byte cache Bytebuffer is used to host the data.
Bytebuffer is located in the Java.nio package and currently provides other types of buffer types in Java primitives other than Boolean, such as Bytebuffer, DoubleBuffer, Floatbuffer, Intbuffer, Longbuffer and Shortbuffer. It also provides a more special mapping byte buffer type Mappedbytebuffer. In the input and output stream of the traditional IO, only the access corresponding to the byte-type or byte-array is provided in InputStream. NiO is Bytebuffer, but the type of int, which handles the traditional datainputstream, is Intbuffer, But the buffer type does not provide type processing like UTF, so we still need to use Bytebuffer to process the string, But NIO provides a encapsulated class in the Java.nio.charset package that handles strings by encoding Charsetencoder and decoding charsetdecoder classes of characters, and these classes can be easily converted to encodings such as GBK or UTF, and so on.
First, Bytebuffer class
1) instantiation
Static methods for directly using the Bytebuffer class static Bytebuffer allocate(int capacity) or static Bytebuffer allocatedirect(int Capacity) These two methods to allocate memory space, the difference between the two methods is mainly the latter more suitable for the complex allocation of byte arrays. The put (Bytebuffer src) can be constructed from another bytebuffer, or it can be constructed from the byte[] by the Wrap method, specifically referring to the following types of conversion content.
2) Type conversion
Bytebuffer can be a good and byte array byte[] conversion type, you can convert Bytebuffer to byte[by executing the Bytebuffer class's final byte[] Array () method. From byte[] to construct bytebuffer you can use the Wrap method, currently Android or Java provides two overriding methods, such as static Bytebuffer wrap (byte[] array) and static Bytebuffer Wrap (byte[] array, int start, int len), the second parameter in the second overloaded method is the initial position of the byte array from array, and the third parameter is the length of the byte array of array.
3) Adding elements to the Bytebuffer
Currently Bytebuffer offers a variety of put rewrite types to add, such as put (Byte b), Putchar (char value), putfloat (float value), and so on, to be aware that, depending on the type length of Java, A byte is 1 bytes, a char type is 2 bytes, a float or int is 4 bytes, a long is 8 bytes, and is somewhat different from the traditional C + +. So the relative position of the interior also changes, and each method also provides a way to locate it, such as Bytebuffer put (int index, byte b)
4) Get elements from Bytebuffer
With the above idea, the various put is replaced with get, such as a Byte get (), float getfloat (), of course, also provides a way to locate, such as double getdouble (int index)
5) Bytebuffer in byte order
For Java, the default is to use the Big_endian method of storage, and C just the opposite, through
Final Byteorder order () returns the current byte order.
Final Bytebuffer order (Byteorder byteorder) sets the byte order, and the value of the Byteorder class has two definitions, such as Little_endian, Big_endian, If you use the current platform, Byteorder.nativeorder () is Big_endian in Android, and Little_endian is used if set to order (NULL).
Second, FileChannel class
In the NIO in addition to the socket, also provides the file device channel class, FileChannel is located in the Java.nio.channels.FileChannel package, in the Android SDK documentation we can easily find, For file replication We can use the Bytebuffer method as a buffer, such as
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); Allocate 1KB as Buffer
while (true) {
Buffer.clear (); Empty buffers must be placed on each use
int r = fcin.read (buffer);
if (r==-1) {
Break
}
Buffer.flip (); Use the Flip method before writing
Fcout.write (buffer);
}
Flip and clear these two methods are Java.nio.Buffer package, Bytebuffer's parent class is inherited from the buffer class, reminding everyone to look at the Android SDK documentation Note inherited Methods, And the JDK document is more straightforward, while copying files using FileChannel's Transferto (long position, long count, Writablebytechannel target) This method can quickly copy files, No need to manage bytebuffer buffers yourself.
Http://www.jb51.net/article/64733.htm
Take a look at Android NiO for the class provided with the socket operation:
One, Serversocketchannel server socket channel find the package named Java.nio.channels.ServerSocketChannel in the Android SDK
In the Java NiO, Serversocketchannel corresponds to the serversocket in the traditional Io, and through the socket () method of the Serversocketchannel class, a traditional ServerSocket object can be obtained. At the same time, a Serversocketchannel () object can be obtained from the Getchannel () method of the ServerSocket object. This indicates that the Serversocketchannel of NIO is associated with the serversocket of the traditional Io, and the instantiation Serversocketchannel only needs to call the static method of the Serversocketchannel class directly open ( To
Second, Socketchannel socket channel Java.nio.channels.SocketChannel
In Java's new I/O, dealing with what the socket class corresponds to, we can be seen as Socketchannel, the socket channel is associated with a socket class, which uses the Socketchannel class socket () Method can return a socket class for a traditional IO. Socketchannel () objects are generally obtained in the server through the Getchannel () method of the socket class.
Three, Selectionkey select key Java.nio.channels.SelectionKey
Selectionkey and selector are the most critical areas in NiO, and the Selectionkey class describes the more important events in NiO, such as op_accept (for server side), Op_connect (for clients), OP_ Read and Op_write.
Iv. Selector Selector Java.nio.channels.Selector
The method of registering events in NIO is primarily implemented using selector, which constructs a selector object and instantiates it using the static method of the Selector class, open ().
For the Android platform we implement a non-blocking server, the process is as follows:
1. Instantiate a selector object by using the open () static method of the selector class.
2. Instantiate a Serversocketchannel object by using the open () static method of the Serversocketchannel class.
3. The configureblocking (false) of the call Serversocketchannel object is displayed, and the method is set to non-blocking mode, which is very important for Android123 to prompt the Netizen.
4. Use the socket () method of the Serversocketchannel object to return an ServerSocket object, bind an IP address and port number using the bind () method of the ServerSocket object
5. Call the Register method of the Serversocketchannel object to register the network event of interest, and many developers may find that the Register method is not seen in the Android SDK documentation. Here the Android development net gives everyone an inheritance relationship of the Serversocketchannel class
Java.lang.Object
? Java.nio.channels.spi.AbstractInterruptibleChannel
? Java.nio.channels.SelectableChannel
? Java.nio.channels.spi.AbstractSelectableChannel
? Java.nio.channels.ServerSocketChannel
The Register method we use here actually comes from Serversocketchannel's parent class Java.nio.channels.SelectableChannel, which is a prototype of the final Selectionkey register (Selector Selector, int operations), parameter for us to perform the 1th step when the Selector object, parameter two is the event that needs to register, as the server, we are of course accept the request sent by the client, So the selectionkey.op_accept is used here.
6. The Op_accept event is determined by the Select () method of the Selector object to determine if an event of interest has occurred. We get the value of the Select () method through a dead loop for the selector object, and the original description in the SDK is the number of channels that is ready for operation., which is exactly how many channels are returned.
7. If the Selector object's Select () method returns more than 0 results, a set collection of Selectionkey types is obtained through the Selectedkeys () method of the Selector object. We use the Java iterator iterator class to iterate over this set set, to be aware of the Selectionkey object,
8. In order to indicate that we have processed the Selectionkey object, we need to remove the Selectionkey object from the set set. This is key. Android 123 reminds netizens to pay attention to this place.
9. Next determine the event of the Selectionkey object, because we are interested in registering the Selectionkey.op_accept event, we use the Selectionkey object's Isacceptable () method to judge, If we create a temporary Socketchannel object similar to the above method to continue processing, but this Socketchannel object mainly handles read and write operations, we register Selectionkey.op_read and SELECTIONKEY.OP_ Write allocates the Bytebuffer buffer for network data transfer.
======== for the development of Android applications, there is no specific scenario with NIO. ===========================================
However, it is used in the official OpenGL tutorials, so record:
/* Copyright (C) The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License") ; * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by appli Cable law or agreed into writing, software * Distributed under the License is distributed on a "as is" BASIS, * without Warranties or CONDITIONS of any KIND, either express OR implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.edaixi.opengl;import java.nio.bytebuffer;import Java.nio.byteorder;import java.nio.FloatBuffer; Import Java.nio.shortbuffer;import javax.microedition.khronos.opengles.gl10;/** * A two-dimensional square for use as A D Rawn object in OpenGL ES 1.0/1.1. */public class Square {private final floatbuffer vertexbuffer; Private final Shortbuffer Drawlistbuffer; Number of CoordInates per vertex in the this array static final int coords_per_vertex = 3; static float squarecoords[] = { -0.5f, 0.5f, 0.0f,//Top left-0.5f, -0.5f, 0.0f,//Bottom Le FT 0.5f, -0.5f, 0.0f,//Bottom right 0.5f, 0.5f, 0.0f}; Top right private final short draworder[] = {0, 1, 2, 0, 2, 3}; Order to draw vertices float color[] = {0.2f, 0.709803922f, 0.898039216f, 1.0f}; /** * Sets up the drawing object data for use with an OpenGL ES context. */Public Square () {//Initialize vertex byte buffer for shape coordinates bytebuffer BB = bytebuffer.al Locatedirect (//(# of coordinate values * 4 bytes per float) squarecoords.length * 4); Bb.order (Byteorder.nativeorder ()); VertexBuffer = Bb.asfloatbuffer (); Vertexbuffer.put (squarecoords); Vertexbuffer.position (0); Initialize byte buffer for the draw list Bytebuffer DLB = BytebuffeR.allocatedirect (//(# of coordinate values * 2 bytes per short) draworder.length * 2); Dlb.order (Byteorder.nativeorder ()); Drawlistbuffer = Dlb.asshortbuffer (); Drawlistbuffer.put (Draworder); Drawlistbuffer.position (0); }/** * Encapsulates the OpenGL ES instructions for drawing this shape. * * @param gl-the OpenGL ES context in which-draw this shape. */public void Draw (GL10 gl) {//Since This shape uses vertex arrays, enable them gl.glenableclientstate (Gl10.gl_vertex_array); Draw the Shape gl.glcolor4f (//Set color color[0], color[1], color[2], Colo R[3]); Gl.glvertexpointer (//point to Vertex Data:coords_per_vertex, gl10.gl_float, 0, Vertexbuff ER); Gl.gldrawelements (//Draw Shape:GL10.GL_TRIANGLES, Draworder.length, Gl10.gl_unsigned_sho Rt Drawlistbuffer); Disable vertex array drawing to avoid//conflicts with shapes that don ' t use it gl.gldisableclientstate ( Gl10.gl_vertex_array); }}
Android NIO (noblocking I/O non-blocking I/O) Summary