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開發藝術探索》一書