Messenger 信使 也是進程間通信的一種方式,但是它的好處在於不用像aidl 一樣必須要定義aidl 接口,然後通過接口來通信,本質上messenger 的實現底層也是通過aidl 實現的。
實現原理是客戶端通過綁定服務端service ,通過返回的IBundle,生成獲取到服務端的Messenger對像,然後通過服務端的Messenger 對象將客戶端的Messenger 發送到服務端,這樣兩端各自持有對方的Messenger 對像,而每個messenger 都會綁定各自的handler對象,所以當發送消息時handler 就會收到,然後就可以愉快的通信了。
本篇代碼將和上篇aidl 使用相同的項目多進程間通信AIIDL使用
步驟如下:
1.服務端 新建兩個項目,一個用於服務端app (aidlapplication),一個用於客戶端app(clientservice)
2.服務端 創建服務端service ,創建Messenger 並通過getBinder獲取 IBinder ,使用onBind返回給客戶端
3.客戶端綁定服務端service,通過IBinder 獲取到服務端Messenger
4.將客戶端的Messenger 發送到服務端
5.兩端可以互相發送消息了
1.服務端 新建兩個項目,一個用於服務端app (aidlapplication),一個用於客戶端app(clientservice)
這步就不多說了,名字大家可以隨意取,這裏只是便於分辯
2.服務端 創建服務端service ,創建Messenger 並通過getBinder獲取 IBinder ,使用onBind返回給客戶端
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
Messenger clientMessenger;
int messageid=0;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==0) {
//獲取客戶端的messenger對象,及初始消息
clientMessenger=msg.replyTo;
}else {
Bundle bundle=msg.getData();
Log.d(TAG, msg.what +"" + "handleMessage: 收到客戶端的消息"+ bundle.getString("ms"));
//發送消息給客戶端我收到你的消息了
Bundle sbundle=new Bundle();
Message message=Message.obtain();
sbundle.putString("cms","這是一條服務端發來的消息" + messageid++);
message.setData(sbundle);
message.what=0x02;
try {
clientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
};
//創建服務端的messenger 對象
Messenger messenger=new Messenger(handler);
}
這裏我們通過onBind 返回了一個IBinder 接口 ,實際是從Messenger中獲取到的IBinder 接口,而Messenger 本身在初始化時又綁定了一個handler ,當客戶端發送消息時服務端的handler 就會收到消息,replyTo 方法用於獲取客戶端的Messenger對象。
很重要的一點,服務端要註冊
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.example.service.messenger"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
3.客戶端綁定服務端service,通過IBinder 獲取到服務端Messenger
通過intent 綁定服務
Intent intent = new Intent();
intent.setPackage("com.example.aidlapplication");
intent.setAction("com.example.service.messenger");
bindService(intent, connection, BIND_AUTO_CREATE);
這裏的package是服務端的包名,action 是註冊時定義的,用於匹配啓動綁定服務。
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
if (serviceMessenger == null) {
try {
throw new IllegalAccessException("綁定成功但是 serviceMessenger 是 null");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
綁定成功後我們獲取到了,服務端的Messenger對象serviceMessenger
4.將客戶端的Messenger 發送到服務端
通過綁定獲取到了服務端的Messenger對象serviceMessenger 然後通過這個serviceMessenger 將客戶端的messenger 發送到
服務端。
這裏需要客戶端先new 一個Messenger cMessenger然後綁定一個handler .
Message message = Message.obtain();
message.what = 0x00;
message.replyTo = cMessenger;
Bundle bundle=new Bundle();
message.setData(bundle);
try {
//發送客戶端Messenger 到服務端,本意在建立鏈接
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
5.兩端可以互相發送消息了
通過上邊的步驟我們兩個端各自獲取到了對方的Messenger 對象,就可以通過這個發送消息到對方了。
我將客戶端的activity 全部粘出來
public class MessageActivity extends Activity {
StringBuilder stringBuilder=new StringBuilder();
private static final String TAG = "MessageActivity";
private Button mMessengerBindService;
private Button mMessengerSendMsToService;
private TextView mmessengerMsShow;
private Button messenger_send_messenger_to_service;
private Button messengerSendMsToService;
private TextView messengerMsShow;
Messenger serviceMessenger;
Handler serviceHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mesenge_layout);
initView();
Intent intent = new Intent();
intent.setPackage("com.example.aidlapplication");
intent.setAction("com.example.service.messenger");
bindService(intent, connection, BIND_AUTO_CREATE);
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
if (serviceMessenger == null) {
try {
throw new IllegalAccessException("綁定成功但是 serviceMessenger 是 null");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Handler cHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what != 0x00) {
stringBuilder.append("\n");
stringBuilder.append( msg.getData().getString("cms"));
Log.d(TAG, "handleMessage: 我收到了服務端發來的消息");
messengerMsShow.setText(stringBuilder.toString());
}else if(msg.what==0){
}
}
};
Messenger cMessenger = new Messenger(cHandler);
public void initView() {
messenger_send_messenger_to_service = findViewById(R.id.messenger_send_messenger_to_service);
messengerSendMsToService = findViewById(R.id.messenger_send_ms_to_service);
messengerMsShow = findViewById(R.id.messenger_ms_show);
messenger_send_messenger_to_service.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 0x00;
message.replyTo = cMessenger;
Bundle bundle=new Bundle();
message.setData(bundle);
try {
//發送客戶端Messenger 到服務端,本意在建立鏈接
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
messengerSendMsToService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 0x02;
Bundle bundle=new Bundle();
bundle.putString("ms","我是客戶端,我向服務端發送了一條請求");
message.setData(bundle);
try {
//發送客戶端Messenger 到服務端
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<Button
android:id="@+id/messenger_send_messenger_to_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="綁定service" />
<Button
android:id="@+id/messenger_send_ms_to_service"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="向服務端發送消息"/>
<TextView
android:id="@+id/messenger_ms_show"
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"/>
</LinearLayout>
資源下載地址:https://download.csdn.net/download/u013179982/12305267