参考:https://blog.csdn.net/u010961631/article/details/48179305
1、AsyncChannel
AsyncChannel的主要特点:
- 可以在单进程或不同进程间实现消息传递
- 支持建立单向通信或双向通信
- 是对Handler,Messenger的一种包装,并没有实现额外的通信方式
1、单项通道模式,在该模式下,客户端只能向服务端发起请求,服务端给出回应。
2、双向通道模式,在该模式下,客户端和服务端同时连接上AsyncChannel,客户端可以向服务端发送请求,服务端也可以向客户端发送请求。
使用实例类图:
2、单向通道建立方法并发送消息
从通道的建立方法可以知道,创建通道需要三个步骤:
1、准备服务端的Messenger对象;
2、创建本地的Handler对象;
3、创建AsyncChannel对象,然后调用connect()方法。
客户端操作:
1、获取服务端的Messenger对象,该对象其实就是利用服务端的Handler构建的Messenger;
2、创建客户端自己的Handler对象;
3、创建AsyncChannel对象;
4、通过AsyncChannel对象,连接当前的Handler和服务端的Messenger,从而申请连接
1、服务启动:
Intent intent = new Intent(); intent.setComponent(new ComponentName(this, AsyncChannelService.class)); startService(intent); Intent inte = new Intent(); inte.setComponent(new ComponentName(this, AsyncChannelClient.class)); inte.setAction("Normal"); startService(inte);
2、客户端发起连接
HandlerThread handlerThread = new HandlerThread("ClientThread"); handlerThread.start(); Handler clientHandler = new ClientHandler(handlerThread.getLooper()); sClientAsyncChannel = new AsyncChannel(); String act = intent.getAction();
Messenger serviceMessenger = AsyncChannelService.getServiceMessenger(); Log.d(tag, "Client Start require half connect"); sClientAsyncChannel.connect(this, clientHandler, serviceMessenger);
3、向服务端发送异步消息
sClientAsyncChannel.sendMessage(MainActivity.MSG_ASYNC_REQ);
服务端接收消息并回复
public void handleMessage(Message msg) { switch (msg.what) { case MainActivity.MSG_ASYNC_REQ: { Log.d(tag, "Service get client ASYNC reqest,next reply to client"); Message reply = msg.obtain(); reply.what = MainActivity.MSG_ASYNC_REPLY; reply.obj = "ServiceAsyncReply"; try { msg.replyTo.send(reply); } catch (RemoteException e) { } break; }
3、双向通道的建立
双向通道是在单项通道基础上完成的,当客户端与服务端的单项通道创建完成后,也就是当客户端收到AsyncChannel.CMD_CHANNEL_HALF_CONNECTED之后,可以向AsyncChannel对象发送CMD_CHANNEL_FULL_CONNECTION消息申请建立双向通道。
1、客户端收到单向通道建立完成消息后,发送消息服务端请求双向通道的建立
public void handleMessage(Message message) { switch (message.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { Log.d(tag, "Client half connected,next send full connect require"); sClientAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
2、服务端收到请求消息,发起连接
public void handleMessage(Message msg) { case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { Log.d(tag, "Service full connected,next require asynchannel connect"); sServiceAsyncChannel.connect(AsyncChannelService.this, mServiceHandler, msg.replyTo); break; }
当客户端发起双向通道建立请求时,服务端将会收到AysncChannel.CMD_CHANNEL_FULL_CONNECTION的请求,此时的服务端如果同意建立双向通道,则使用自己的AsyncChannel对象将自己的Handler与客户端的Handler连接起来。
至此,双向通道建立完成,此时不仅客户端可以通过自己的AsyncChannel对象向服务端发送请求,服务端也可以通过自己的AsyncChannel对象向客户端发送请求。
3、发送同步消息
客户端:
Message replyMsg = sClientAsyncChannel.sendMessageSynchronously(MainActivity.MSG_SYNC_REQ);
String msg = (String) replyMsg.obj;
服务端:
public void handleMessage(Message msg) { case MainActivity.MSG_SYNC_REQ: { Log.d(tag, "Service get client SYNC reqest,next reply to client"); Message reply = msg.obtain(); reply.what = MainActivity.MSG_SYNC_REPLY; reply.obj = "ServiceSyncReply"; sServiceAsyncChannel.replyToMessage(msg, reply); break; }
4、fullyConnectSync 建立双向通道
fullyConnectSync()方法。通过该方法,客户端只需要一次就可以申请到双向通道,并且可以知道通道是否建立成功
1、服务的启动
Intent intent = new Intent(); intent.setComponent(new ComponentName(this, AsyncChannelServiceFull.class)); startService(intent); Intent inte = new Intent(); inte.setComponent(new ComponentName(this, AsyncChannelClient.class)); inte.setAction("Fast"); startService(inte);
2、客户端发起同步双向通道的连接fullyConnectSync
Handler serviceHandler = AsyncChannelServiceFull.getServiceHandler(); Log.d(tag, "Client Start require full connect"); int result = sClientAsyncChannel.fullyConnectSync(this, clientHandler, serviceHandler); if (AsyncChannel.STATUS_SUCCESSFUL == result) { Log.d(tag, "client full connected"); }
3、服务端收到同向双向通道连接请求,发起连接,并回复连接完成
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { Log.d(tag, "FullService received full connect require,reply OK to channel"); sServiceAsyncChannel.connect(AsyncChannelServiceFull.this, mServiceHandler, msg.replyTo); sServiceAsyncChannel.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, AsyncChannel.STATUS_SUCCESSFUL); break; }