AIDL可以實現進程間通信,但使用稍顯複雜,Messenger也可以實現進程間通信,Messenger底層實現利用了 AIDL ,系統已經幫我們完成了Aidl的書寫。Messenger可以在不同進程中傳遞 Message 對象,利用Handler一次只處理一個請求,不存在併發執行的情形。所以這是Messenger的優點,也是它的缺點,它無法用於大量的併發操作,但對於簡單的進程間通信則十分好用。利用bindService客戶端和服務端可以拿到對方的 Messenger 來發送 Message 的。客戶端通過 bindService onServiceConnected ,服務端通過 message.replyTo 來獲得對方的 Messenger 。
下面的例子,服務器和客戶端是兩個應用。
1 服務器端寫法
定義一個Service,利用自定義handler生成Messenger,然後在onBind中獲取它的binder,client端可以進行
public class MessengerService extends Service {
private static final String TAG = MessengerService.class.getSimpleName();
//服務器Messenger
private Messenger serviceMessenger = new Messenger(new MessengerHandler());
private class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if (msg.what == 2) {
System.out.println("===========getDataFromClient=========" + msg.getData().getString("data"));
//獲取客戶端的Messenger
Messenger client = msg.replyTo;
//新建也行
Message replymsg = Message.obtain(null, 1);
Bundle bundle = new Bundle();
bundle.putString("data", "服務器回覆信息");
//向客戶端發送信息
replymsg.setData(bundle);
try {
client.send(replymsg);
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
super.handleMessage(msg);
}
}
}
public MessengerService() {
}
@Override
public IBinder onBind(Intent intent) {
return serviceMessenger.getBinder();
}
}
AndroidManifest.xml中聲明,由於需要外部調用(隱式啓動)exported= true,還需要設置action
<service
android:name=".service.MessengerService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.ldx.demo.messenger.service" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
2 客戶端
客戶端通過綁定service,獲取服務器的Messenger,通過服務器Messenger的replyTo指向客戶端的Messenger發送信息。
public class ClientActivity extends AppCompatActivity {
TextView mStart;
TextView mSend;
TextView mData;
//客戶端messenger
private Messenger mClientMessenger = new Messenger(new MessageHandler());
private Messenger mServiceMessenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
mStart = findViewById(R.id.start_service);
mSend = findViewById(R.id.send_message);
mData = findViewById(R.id.get_message);
initEvent();
}
private void initEvent() {
mStart.setOnClickListener(view -> {
bindService();
});
mSend.setOnClickListener(view -> {
sendMessage();
});
}
private void bindService(){
Intent intent = new Intent();
intent.setAction("com.ldx.demo.messenger.service");
bindService(intent, mConnection, Service.BIND_AUTO_CREATE);
}
private class MessageHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1){
System.out.println("============收到服務器信息=========="+msg.getData().get("data"));
if (mData != null){
String data = mData.getText().toString();
if (data != null){
mData.setText(data+"\n"+"服務器發送的消息:"+msg.getData().get("data"));
}
}
}else{
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
//獲取服務器Messenger
mServiceMessenger = new Messenger(service);
Message message = Message.obtain(null,2);
message.replyTo = mClientMessenger;
mServiceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceMessenger = null;
}
};
public void sendMessage() {
if (mServiceMessenger != null){
Message msg = Message.obtain(null,2);
Bundle data = new Bundle();
data.putString("data", "我是客戶端");
msg.setData(data);
msg.replyTo = mClientMessenger;
try {
//發送信息
mServiceMessenger.send(msg);
if (mData != null){
String str = mData.getText().toString();
if (str != null){
String str2 = str+"\n"+"client發送的消息:"+"我是客戶端";
mData.setText(str2);
}
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
result: