Android中使用跨進程通信有以下幾種方式:文件、廣播添瓷、aidl、messenger,今天要講的是使用messenger來實現(xiàn)跨app通信也就是在兩個不同的app中實現(xiàn)雙向通信。其實Messenger底層也是使用aidl的方式來實現(xiàn)的,只不過其使用handler來處理消息戳杀,因為handler是線程安全的,所以Messenger也是線程安全的夭苗,自然Messenger只能處理單線程的問題信卡,如果要使用多線程就該使用aidl的方式實現(xiàn)。
我們來說下通信的大致流程:首先我們創(chuàng)建兩個應(yīng)用A题造、B傍菇,在應(yīng)用B中創(chuàng)建一個Service取名:BService,然后我們在A中通過bindService來綁定BService,這樣之后兩個App就實現(xiàn)了破冰之旅。
上面的情況只是說明了大體的流程晌梨,具體如何實現(xiàn)綁定遠程的BService和如何在BService中來回復(fù)A應(yīng)用桥嗤,這里我詳細(xì)的說下。我們知道bindService()方法中需要三個參數(shù)仔蝌,
bindService(intent,serviceConnection,BIND_AUTO_CREATE);
第一個為Intent對象,第二個為ServiceConnection荒吏,最后一個參數(shù)為如何去綁定敛惊,一般都是寫的這個值。這些相信大家都非常的清楚了绰更,和平時的綁定服務(wù)是一樣的瞧挤,我們做的也是一樣的锡宋,不同的是在ServiceConnection中,我們這樣處理返回的IBinder:
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("kk", "鏈接斷開特恬!");
}
};
我們看到执俩,這里我們使用IBinder來創(chuàng)建Messenger對象,然后我們就可以使用這個mesender來像遠程的服務(wù)發(fā)送數(shù)據(jù):
Message message = Message.obtain(null, 1);
Bundle bundle = new Bundle();
bundle.putString("data", "我要和B說話!");
message.setData(bundle);
try {
messenger.send(message);//發(fā)送數(shù)據(jù)
} catch (RemoteException e) {
e.printStackTrace();
}
這里我們使用messenger.send()方法來發(fā)送數(shù)據(jù)癌刽。下面我們來看看BService中的代碼:
public class BService extends Service {
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
});
@Override
public IBinder onBind(Intent intent) {
Log.e("kk", "綁定成功役首!");
return messenger.getBinder();
}
}
這里我們使用Messenger.getBinder()方法返回IBinder,和A中的代碼做比較我們就會發(fā)現(xiàn)显拜,這里使用messenger的getBinder()返回IBinder衡奥,A中又通過返回的IBinder創(chuàng)建了一個Messenger對象,所以他們都是用的同一個IBinder對象远荠,這樣通過Messenger發(fā)送的消息自然是會在B中的Messenger創(chuàng)建時候的Handler里面來處理了矮固,這樣就實現(xiàn)了A像B應(yīng)用發(fā)送消息。
那么B中如何像A發(fā)送消息呢譬淳?档址??我們知道?Message中有屬性:replyTo邻梆,該屬性是一個Messenger類別的守伸,如果我們在A類中將該屬性賦值給一個Messenger對象,然后在B類中獲取到該對象然后通過其發(fā)送消息确虱,這樣消息自然就會在A類中的Messenger中來處理含友,這樣就實現(xiàn)了B類向A類發(fā)送消息,到這里我們就實現(xiàn)了雙向的通信校辩,具體修改后的代碼這里我貼出來窘问,首先是A類:
message.replyTo = replyMessenger;
essenger replyMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("kk", msg.getData().getString("data"));
super.handleMessage(msg);
}
});
然后是在B類中:
public class BService extends Service {
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("kk", msg.getData().getString("data"));
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("data","你要說什么?");
message.setData(bundle);
try {
msg.replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
super.handleMessage(msg);
}
});
@Override
public IBinder onBind(Intent intent) {
Log.e("kk", "綁定成功宜咒!");
return messenger.getBinder();
}
}
我再貼出A類中所有的代碼:
public class MainActivity extends AppCompatActivity {
Messenger messenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
messenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("kk", "鏈接斷開惠赫!");
}
};
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.leixinxue.b", "com.example.leixinxue.b.BService"));
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
public void sendMessageToB(View view) {
Message message = Message.obtain(null, 1);
message.replyTo = replyMessenger;
Bundle bundle = new Bundle();
bundle.putString("data", "我要和B說話!");
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
Messenger replyMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("kk", msg.getData().getString("data"));
super.handleMessage(msg);
}
});
}
A類的布局文件:
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="sendMessageToB"
android:text="發(fā)送消息!" />
好啦,這里兩個類就可以實現(xiàn)通信了故黑,點擊A類中的發(fā)送消息按鈕就可以給B發(fā)送一條消息儿咱,B收到消息后立馬回復(fù)一個消息給A。
總結(jié):
兩個app間通信通過Messenger其實很簡單的场晶,就是通過bindService綁定到遠程的service混埠,然后用在綁定的Serviceconnection中返回的IBinder來創(chuàng)建一個Messenger對象,通過Messenger的send發(fā)送消息到遠程的服務(wù)诗轻,遠程的服務(wù)通過Message中的屬性replyTo就可以回復(fù)收到的消息钳宪,不要忘了給replyTo賦值。好了,詳細(xì)我已經(jīng)將的很詳細(xì)了吏颖,如果你還有什么疑問搔体,歡迎給我留言,bye~~
資源下載:
歡迎關(guān)注我的微信公眾號“AndroidBook”半醉,也可以掃描下面的二維碼來關(guān)注: