? ? ? ?需求是實(shí)現(xiàn)兩個(gè)APP的通信,組長(zhǎng)讓廣播來(lái)實(shí)現(xiàn),一把梭完事。閑下來(lái)想起之前客戶用Service里面的東西來(lái)實(shí)現(xiàn)跨進(jìn)程通信。所以研究了一下,原來(lái)就是用到的Messenger。
? ? ? ?因?yàn)槟M兩個(gè)APP 我就寫兩個(gè)APP 來(lái)說(shuō)這個(gè)Messenger,首先APP B的Sevice:
public class BService extends Service{
//記錄下客戶端發(fā)過(guò)來(lái)的Messenger
Messenger sendMessenger ;
//接受客戶端發(fā)過(guò)來(lái)的消息
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("kk", msg.getData().getString("data"));
sendMessenger = msg.replyTo;
sendMsg();
super.handleMessage(msg);
}
});
//服務(wù)器綁定成功 將IBinder 返回給客戶端
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
private void sendMsg(){
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("data","綁定成功?");
message.setData(bundle);
try {
sendMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
? ? ? ?這個(gè)就是APP B的代碼,然后在MainActivity中StartService 就可以了。 Mainfest.xml中加上這些。運(yùn)行那么這個(gè)服務(wù)器就算完成了。
<service
android:name=".BService"
android:enabled="true"
android:exported="true"></service>
然后來(lái)看APP A 這里稱呼為客戶端 代碼就一個(gè)類
public class MainActivity extends AppCompatActivity {
public Messenger messenger ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//一個(gè)按鈕來(lái)發(fā)消息
Button btnPlay = (Button) findViewById(R.id.btn_paly);
connectService();
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Message message = Message.obtain(null, 1);
//把自己的Messenger帶進(jìn)去 服務(wù)器拿到之后 可以直接通過(guò)這個(gè)對(duì)象發(fā)數(shù)據(jù)過(guò)來(lái)
message.replyTo = replyMessenger;
Bundle bundle = new Bundle();
bundle.putString("data", "服務(wù)器你好");
message.setData(bundle);
try {
//發(fā)送消息的方法
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
/**
* 和服務(wù)器建立連接 連接成功之后 messenger 就是發(fā)消息的對(duì)象。
**/
private void connectService(){
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("kk", "鏈接成功!");
messenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("kk", "鏈接斷開!");
}
};
Intent intent = new Intent();
intent.setComponent(new ComponentName("第一個(gè)應(yīng)用的包名", "第一個(gè)應(yīng)用的包名+Service名稱"));
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
//這個(gè)Service的Messenger
Messenger replyMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Log.e("kk", msg.getData().getString("data"));
super.handleMessage(msg);
}
});
}
? ? ? ?這個(gè)APP 就只有一個(gè)按鈕 點(diǎn)擊就發(fā)送一個(gè)服務(wù)器你好,其實(shí)很是簡(jiǎn)單,就是建立兩個(gè)Service 的綁定,記錄一下跨進(jìn)程通信的一個(gè)方式 這個(gè)底層說(shuō)是封裝好的AIDL,比廣播效率高,通信方向是雙向。網(wǎng)上有的Demo只寫出了如何通過(guò)客戶端觸發(fā)服務(wù)器讓服務(wù)器發(fā)消息給客戶端。但是要服務(wù)器主動(dòng)發(fā)消息給客戶端卻沒有寫出來(lái),其實(shí)很簡(jiǎn)單 就是把 B中的msg.replytTo 用Messenger 對(duì)象接受 不能直接用一個(gè)Messahe 對(duì)象來(lái)接Msg對(duì)象 ,這樣就不能主動(dòng)的發(fā)消息了。
Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
//錯(cuò)誤寫法 Message sendMessenger= msg ;
//正確寫法
sendMessenger = msg.replyTo;
最后調(diào)用sendMessenger.send(""需要傳的內(nèi)容)
super.handleMessage(msg);
}
});
好了 Messenger就可以 雙向通信了,不分主次了