Android 使用Messenger實(shí)現(xiàn)跨app通信

Android中使用跨進(jìn)程通信有以下幾種方式:文件、廣播、aidl、messenger,今天要講的是使用messenger來實(shí)現(xiàn)跨app通信也就是在兩個(gè)不同的app中實(shí)現(xiàn)雙向通信。其實(shí)Messenger底層也是使用aidl的方式來實(shí)現(xiàn)的,只不過其使用handler來處理消息,因?yàn)閔andler是線程安全的,所以Messenger也是線程安全的,自然Messenger只能處理單線程的問題,如果要使用多線程就該使用aidl的方式實(shí)現(xiàn)。

我們來說下通信的大致流程:首先我們創(chuàng)建兩個(gè)應(yīng)用A、B,在應(yīng)用B中創(chuàng)建一個(gè)Service取名:BService,然后我們在A中通過bindService來綁定BService,這樣之后兩個(gè)App就實(shí)現(xiàn)了破冰之旅。

上面的情況只是說明了大體的流程,具體如何實(shí)現(xiàn)綁定遠(yuǎn)程的BService和如何在BService中來回復(fù)A應(yīng)用,這里我詳細(xì)的說下。我們知道bindService()方法中需要三個(gè)參數(shù),

bindService(intent,serviceConnection,BIND_AUTO_CREATE);

第一個(gè)為Intent對象,第二個(gè)為ServiceConnection,最后一個(gè)參數(shù)為如何去綁定,一般都是寫的這個(gè)值。這些相信大家都非常的清楚了,和平時(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對象,然后我們就可以使用這個(gè)mesender來像遠(yuǎn)程的服務(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)建了一個(gè)Messenger對象,所以他們都是用的同一個(gè)IBinder對象,這樣通過Messenger發(fā)送的消息自然是會在B中的Messenger創(chuàng)建時(shí)候的Handler里面來處理了,這樣就實(shí)現(xiàn)了A像B應(yīng)用發(fā)送消息。

那么B中如何像A發(fā)送消息呢???我們知道?Message中有屬性:replyTo,該屬性是一個(gè)Messenger類別的,如果我們在A類中將該屬性賦值給一個(gè)Messenger對象,然后在B類中獲取到該對象然后通過其發(fā)送消息,這樣消息自然就會在A類中的Messenger中來處理,這樣就實(shí)現(xiàn)了B類向A類發(fā)送消息,到這里我們就實(shí)現(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ā)送消息!" />

好啦,這里兩個(gè)類就可以實(shí)現(xiàn)通信了,點(diǎn)擊A類中的發(fā)送消息按鈕就可以給B發(fā)送一條消息,B收到消息后立馬回復(fù)一個(gè)消息給A。

總結(jié):

兩個(gè)app間通信通過Messenger其實(shí)很簡單的,就是通過bindService綁定到遠(yuǎn)程的service,然后用在綁定的Serviceconnection中返回的IBinder來創(chuàng)建一個(gè)Messenger對象,通過Messenger的send發(fā)送消息到遠(yuǎn)程的服務(wù),遠(yuǎn)程的服務(wù)通過Message中的屬性replyTo就可以回復(fù)收到的消息,不要忘了給replyTo賦值。好了,詳細(xì)我已經(jīng)將的很詳細(xì)了,如果你還有什么疑問,歡迎給我留言,bye~~

資源下載:

點(diǎn)擊打開鏈接





歡迎關(guān)注我的微信公眾號“AndroidBook”,也可以掃描下面的二維碼來關(guān)注:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容