ASyncChannel 的作用和原理

參考: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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章