Android多進程系列
Messenger也能夠做爲Android多進程的一種通訊方式,經過構建Message來在客戶端和服務端之間傳遞數據
簡單使用Messenger
客戶端經過Messenger向服務端進程發送消息
public class MessengerService extends Service {
private static final String TAG = "MessagerService";
/**
* 處理來自客戶端的消息,並用於構建Messenger
*/
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case MESSAGE_FROM_CLIENT:
Log.e(TAG, "receive message from client:" + message.getData().getString("msg"));
break;
default:
super.handleMessage(message);
break;
}
}
}
/**
* 構建Messenger對象
*/
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
//將Messenger對象的Binder返回給客戶端
return mMessenger.getBinder();
}
}
複製代碼
<service
android:name="com.xxq2dream.service.MessengerService"
android:process=":remote" />
複製代碼
- 而後客戶端是經過綁定服務端返回的binder來建立Messenger對象,並經過這個Messenger對象來向服務端發送消息
public class MessengerActivity extends AppCompatActivity {
private static final String TAG = "MessengerActivity";
private Messenger mService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis());
//經過服務端返回的Binder建立Messenger
mService = new Messenger(iBinder);
//建立消息,經過Bundle傳遞數據
Message message = Message.obtain(null, MESSAGE_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg", "hello service,this is client");
message.setData(bundle);
try {
//向服務端發送消息
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected-->binder died");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//綁定服務
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
//解綁服務
unbindService(mConnection);
super.onDestroy();
}
}
複製代碼
經過上面的實踐,咱們能夠看出利用Messenger進行跨進程通訊,須要經過Message來傳遞消息,而Message能夠經過setData方法利用Bundle來傳遞複雜的數據。
服務端若是要回復消息給客戶端,那就要用到Message的replyTo參數了
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case Constant.MESSAGE_FROM_CLIENT:
Log.e(TAG, "receive message from client:" + message.getData().getString("msg"));
//獲取客戶端傳遞過來的Messenger,經過這個Messenger回傳消息給客戶端
Messenger client = message.replyTo;
//固然,回傳消息仍是要經過message
Message msg = Message.obtain(null, Constant.MESSAGE_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("msg", "hello client, I have received your message!");
msg.setData(bundle);
try {
client.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(message);
break;
}
}
}
複製代碼
- 客戶端改造,主要是經過Handle構建一個Messenger對象,並在向服務端發送消息的時候,經過Message的replyTo參數將Messenger對象傳遞給服務端
/**
* 用於構建客戶端的Messenger對象,並處理服務端的消息
*/
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case Constant.MESSAGE_FROM_SERVICE:
Log.e(TAG, "receive message from service:" + message.getData().getString("msg"));
break;
default:
super.handleMessage(message);
break;
}
}
}
/**
* 客戶端Messenger對象
*/
private Messenger mClientMessenger = new Messenger(new MessengerHandler());
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis());
mService = new Messenger(iBinder);
Message message = Message.obtain(null, MESSAGE_FROM_CLIENT);
Bundle bundle = new Bundle();
bundle.putString("msg", "hello service,this is client");
message.setData(bundle);
//將客戶端的Messenger對象傳遞給服務端
message.replyTo = mClientMessenger;
try {
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected-->binder died");
}
};
複製代碼
總結
- 使用Messager來傳遞Message,Message中能使用的字段只有what、arg一、arg二、Bundle和replyTo,自定義的Parcelable對象沒法經過object字段來傳輸
- Message中的Bundle支持多種數據類型,replyTo字段用於傳輸Messager對象,以便進程間相互通訊
- Messager以串行的方式處理客戶端發來的消息,不適合有大量併發的請求
- Messager方法只能傳遞消息,不能跨進程調用方法
歡迎關注個人微信公衆號,期待與你一塊兒學習,一塊兒交流,一塊兒成長!
複製代碼