日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

messenger android 4.,AndroidIPC机制(4)-Messenger

發(fā)布時間:2024/10/14 135 豆豆
生活随笔 收集整理的這篇文章主要介紹了 messenger android 4.,AndroidIPC机制(4)-Messenger 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、概述

除了使用 AIDL 進行 IPC 外,我們還可以使用 Messenger 來替代 AIDL。通過在 Message 對象中放入需要傳遞的對象,利用 Messenger 在不同進程間傳遞 Message 對象,就可以方便地進行進程間通信了

Messenger 是一種輕量級的 IPC 方案,底層實現(xiàn)依然是 AIDL,通過 Messenger 的兩個構(gòu)造方法就可以看出來

public Messenger(Handler target) {

mTarget = target.getIMessenger();

}

public Messenger(IBinder target) {

mTarget = IMessenger.Stub.asInterface(target);

}

Messenger 對 AIDL 進行了封裝,使開發(fā)者可以更簡單地進行進程間通信。此外,由于 Messenger 一次只處理一個請求,不會出現(xiàn)并發(fā)執(zhí)行的問題,因此在服務(wù)端不用考慮進行線程同步

這里通過 Messenger 來實現(xiàn)一個簡單的進程間通信,客戶端發(fā)送一個整數(shù)給服務(wù)端,服務(wù)端再把這個數(shù)值打印出來

二、服務(wù)端

與 AIDL 一樣,服務(wù)端也要創(chuàng)建一個 Service 來處理客戶端的連接請求,但服務(wù)端的代碼要簡單得多

首先,通過一個 Handler 對象來創(chuàng)建 Messenger 對象,然后在 onBind 方法中返回 Messenger 對象底層的 Binder 即可

/**

* 作者:葉應(yīng)是葉

* 時間:2018/3/22 20:13

* 描述:https://github.com/leavesC

*/

public class MessengerService extends Service {

private static final String TAG = "MessengerService";

private static final int CODE_MESSAGE = 1;

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case CODE_MESSAGE: {

Log.e(TAG, "服務(wù)端收到了消息:" + msg.arg1);

break;

}

}

}

}

private Messenger messenger = new Messenger(new MessengerHandler());

public MessengerService() {

}

@Override

public IBinder onBind(Intent intent) {

return messenger.getBinder();

}

}

三、客戶端

客戶端首先要綁定服務(wù)端的 Service,綁定成功后通過 ServiceConnection 對象的 onServiceConnected 方法的參數(shù) IBinder 來構(gòu)造一個 Messenger 對象,之后通過 Messenger 對象即可向服務(wù)端發(fā)送消息了

/**

* 作者:葉應(yīng)是葉

* 時間:2018/3/22 20:13

* 描述:https://github.com/leavesC

*/

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";

private static final int CODE_MESSAGE = 1;

private Messenger messenger;

private ServiceConnection serviceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

messenger = new Messenger(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

messenger = null;

}

};

private EditText et_message;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

bindService();

initView();

}

@Override

protected void onDestroy() {

super.onDestroy();

unbindService(serviceConnection);

}

private void bindService() {

Intent intent = new Intent();

intent.setClassName("com.czy.messenger_server", "com.czy.messenger_server.MessengerService");

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

}

private void initView() {

et_message = findViewById(R.id.et_message);

Button btn_sendMessage = findViewById(R.id.btn_sendMessage);

btn_sendMessage.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (messenger == null) {

return;

}

String content = et_message.getText().toString();

if (TextUtils.isEmpty(content)) {

return;

}

int arg1 = Integer.valueOf(content);

Message message = new Message();

message.what = CODE_MESSAGE;

message.arg1 = arg1;

try {

messenger.send(message);

Log.e(TAG, "消息發(fā)送成功");

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

}

}

運行結(jié)果如下所示

在上面的示例代碼中我是用 Message 來承載需要發(fā)送的消息的,因為 Messenger 和 Message 都實現(xiàn)了 Parcelable 接口,所以可以跨進程傳輸。Message 中能用來承載數(shù)據(jù)的載體有 what、arg1、arg2、obj、Bundle、replyTo。當(dāng)中,obj 字段在跨進程通信中只能用來承載系統(tǒng)提供的實現(xiàn)了 Parcelable 接口的對象,例如 Bundle 和 Intent。如果承載了非法數(shù)據(jù)(例如 String),則會發(fā)生運行時異常

四、雙向通信

以上的例子只是實現(xiàn)了單向通信,還要考慮下如何實現(xiàn)雙向通信,即服務(wù)端如何向客戶端反饋數(shù)據(jù)?這就需要客戶端也需要通過 Handler 創(chuàng)建一個 Messenger 對象,并將該 Messenger 對象通過 Message 的 replyTo 參數(shù)傳遞給服務(wù)端,服務(wù)端取得該參數(shù)就可以回應(yīng)客戶端了

這里就直接修改上述 IPC 流程,將客戶端發(fā)給服務(wù)端的 arg1 參數(shù)乘以 2 后再返回給客戶端

首先修改服務(wù)端代碼

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case CODE_MESSAGE: {

Log.e(TAG, "服務(wù)端收到了消息:" + msg.arg1 + " " + ((Intent) msg.obj).getAction());

//取得客戶端的 Messenger 對象

Messenger messenger = msg.replyTo;

Message message = new Message();

message.what = CODE_MESSAGE;

message.arg1 = 2 * msg.arg1;

try {

messenger.send(message);

Log.e(TAG, "服務(wù)端回復(fù)消息成功");

} catch (RemoteException e) {

e.printStackTrace();

}

break;

}

}

}

}

為了接收服務(wù)端的回復(fù),客戶端也需要通過 Handler 創(chuàng)建一個 Messenger 對象,并將該 Messenger 對象通過 Message 的 replyTo 參數(shù)傳遞給服務(wù)端

private Messenger replyMessenger;

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case CODE_MESSAGE: {

Log.e(TAG, "客戶端收到了服務(wù)端回復(fù)的消息:" + msg.arg1);

break;

}

}

}

}

btn_sendMessage.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (messenger == null) {

return;

}

String content = et_message.getText().toString();

if (TextUtils.isEmpty(content)) {

return;

}

int arg1 = Integer.valueOf(content);

Intent intent = new Intent("Action");

Message message = new Message();

message.what = CODE_MESSAGE;

message.arg1 = arg1;

message.obj = intent;

//雙向通信時需要加上這一句

message.replyTo = replyMessenger;

try {

messenger.send(message);

Log.e(TAG, "消息發(fā)送成功");

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

運行結(jié)果如下所示

從以上介紹可以看出來,Messenger 的使用要比 AIDL 簡單得多,因為 Messenger 對 AIDL 進行了封裝,使之更加容易使用。但需要注意的是,Messenger 是以串行的方式處理客戶端發(fā)送的消息,即使有大量的消息同時到達服務(wù)端,服務(wù)端也只能一個個處理,所以 Messenger 不適合用于處理大量的并發(fā)請求,此時就還是需要考慮使用 AIDL 了,因為 AIDL 支持并發(fā)通信

這里提供本系列文章所有的 IPC 示例代碼:IPCSamples

總結(jié)

以上是生活随笔為你收集整理的messenger android 4.,AndroidIPC机制(4)-Messenger的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。