日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

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

一、概述

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

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

public Messenger(Handler target) {

mTarget = target.getIMessenger();

}

public Messenger(IBinder target) {

mTarget = IMessenger.Stub.asInterface(target);

}

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

這里通過 Messenger 來實現一個簡單的進程間通信,客戶端發送一個整數給服務端,服務端再把這個數值打印出來

二、服務端

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

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

/**

* 作者:葉應是葉

* 時間: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, "服務端收到了消息:" + msg.arg1);

break;

}

}

}

}

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

public MessengerService() {

}

@Override

public IBinder onBind(Intent intent) {

return messenger.getBinder();

}

}

三、客戶端

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

/**

* 作者:葉應是葉

* 時間: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, "消息發送成功");

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

}

}

運行結果如下所示

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

四、雙向通信

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

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

首先修改服務端代碼

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case CODE_MESSAGE: {

Log.e(TAG, "服務端收到了消息:" + 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, "服務端回復消息成功");

} catch (RemoteException e) {

e.printStackTrace();

}

break;

}

}

}

}

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

private Messenger replyMessenger;

private static class MessengerHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case CODE_MESSAGE: {

Log.e(TAG, "客戶端收到了服務端回復的消息:" + 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, "消息發送成功");

} catch (RemoteException e) {

e.printStackTrace();

}

}

});

運行結果如下所示

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

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。