IPC進程間通信的使用(二)——Messenger

Android開發中通過Messenger可以在不同進程中傳遞Message對象,在Message放入我們需要傳遞的數據,就可以輕鬆實現數據的進程間傳遞了。Messenger是一種輕量級的IPC方案,它的底層實現是了AIDL。
關於Messenger的使用記錄如下:

服務端

服務端創建一個Service來處理客戶端連接請求,同時創建一個Handler並通過它來創建一個Messenger對象,然後在Service的onBind中返回這個Messenger對象底層的Binder即可

清單文件配置:

這裏我將服務端和客戶端寫在不通的app中,清單文件中service添加導出配置android:exported="true"

        <service
            android:name=".MessengerService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.kevin.messenger" />
            </intent-filter>

        </service>
服務端代碼:

只接收客戶端發送的消息,還未和客戶端進行互動。

/**
 * Created by Kevin on 2019/4/9<br/>
 * Blog:https://blog.csdn.net/student9128<br/>
 * Describe:<br/>
 */
public class MessengerService extends Service {
    private static final String TAG = "MessengerService";

    private static class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1001:
                    Log.d(TAG, "receive msg from client:" + msg.getData().getString("msg"));
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    private final Messenger mMessenger = new Messenger(new MessengerHandler());

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
}

可以看到,服務器收到了客戶端發來的消息
在這裏插入圖片描述

客戶端

客戶端,首先綁定服務端的Service,綁定成功後,用服務端返回的IBinder對象創建一個Messenger,通過這個Messenger就可以向服務端發送消息了,發消息類型爲Message對象。

/**
 * Created by Kevin on 2019/4/9<br/>
 * Blog:https://blog.csdn.net/student9128<br/>
 * Describe:<br/>
 */
public class MessengerActivity extends AppCompatActivity {
    private ServiceConnection mSC;
    private Messenger mService;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.kevin.serverclient", "com.kevin.serverclient.MessengerService"));
        intent.setAction("com.kevin.messenger");
        mSC = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = new Messenger(service);
                Message msg = Message.obtain(null, 1001);
                Bundle bundle = new Bundle();
                bundle.putString("msg", "Hello, this msg is from client");
                msg.setData(bundle);
                try {
                    mService.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        bindService(intent, mSC, Context.BIND_AUTO_CREATE);

    }

    @Override
    protected void onDestroy() {
        unbindService(mSC);
        super.onDestroy();
    }
}

如果需要服務端能夠迴應客戶端,就和服務端一樣,還需要創建一個Handler並創建一個新的Messenger,並把這個Messenger對象通過Message的replyTo參數傳遞給服務端,服務端通過這個replyTo參數就可以迴應客戶端。

/**
 * Created by Kevin on 2019/4/9<br/>
 * Blog:https://blog.csdn.net/student9128<br/>
 * Describe:<br/>
 */
public class MessengerActivity extends AppCompatActivity {
    private ServiceConnection mSC;
    private Messenger mService;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.kevin.serverclient", "com.kevin.serverclient.MessengerService"));
        intent.setAction("com.kevin.messenger");
        mSC = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = new Messenger(service);
                Message msg = Message.obtain(null, 1001);
                Bundle bundle = new Bundle();
                bundle.putString("msg", "Hello, this msg is from client");
                msg.setData(bundle);
                msg.replyTo = m;//這裏將Messenger對象傳給服務端,等待服務端迴應
                try {
                    mService.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        bindService(intent, mSC, Context.BIND_AUTO_CREATE);

    }

    private static class ReplyMessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1002:
                    String s = msg.getData().getString("replyTo");
                    Log.d("MessengerActivity", "收到來自服務器回覆:" + s);
                    break;
            }
        }
    }

    private Messenger m = new Messenger(new ReplyMessengerHandler());

    @Override
    protected void onDestroy() {
        unbindService(mSC);
        super.onDestroy();
    }
}

服務端要怎麼迴應客戶端呢?
如下,在收到客戶端的打招呼後,服務端拿到客戶端給的replyTo參數,也就是Messenger對象,Messenger將回應的消息存在Message對象發送出去。

      Messenger messenger = msg.replyTo;
      Message s = Message.obtain(null,1002);
      Bundle bundle = new Bundle();
      bundle.putString("replyTo","Nice to receive your message! This is server");
      s.setData(bundle);
      try {
            messenger.send(s);
          } catch (RemoteException e) {
          e.printStackTrace();
          }

如下圖,客戶端收到了服務端的迴應消息。
在這裏插入圖片描述
服務端的完整代碼:

/**
 * Created by Kevin on 2019/4/9<br/>
 * Blog:https://blog.csdn.net/student9128<br/>
 * Describe:<br/>
 */
public class MessengerService extends Service {
    private static final String TAG = "MessengerService";

    private static class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1001:
                    Log.d(TAG, "receive msg from client:" + msg.getData().getString("msg"));
                    Messenger messenger = msg.replyTo;
                    Message s = Message.obtain(null,1002);
                    Bundle bundle = new Bundle();
                    bundle.putString("replyTo","Nice to receive your message! This is server");
                    s.setData(bundle);
                    try {
                        messenger.send(s);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    private final Messenger mMessenger = new Messenger(new MessengerHandler());

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
}

注:本文章知識點來自學習《Android開發藝術探索》一書

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