Android通信关于Messenger的使用

简单介绍

Messenger是基于binder实现的轻量化的IPC通信方式。

服务端代码

以下是关于继承service实现的服务的相关代码,重点是onBind方法的返回对象,会在client端连接后通过binder获取到。

package com.example.test.messenger;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class MessengerService extends Service {

    private static final String TAG = "MessengerService";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Messenger messenger = new Messenger(new Handler(this.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Log.d(TAG, "MessengerService handleMessage msg.what = " + msg.what);
                switch (msg.what) {
                    case 1: // 客户端发送消息时携带的what标记
                        String bundleValue = msg.getData().getString("bundle_key");
                        Log.d(TAG, "bundleValue = " + bundleValue);
                        // 获取到client端Messenger对象
                        Messenger clientMessenger = msg.replyTo;
                        Log.d(TAG, "clientMessenger = " + clientMessenger);
                        Message toClientMsg = Message.obtain();
                        toClientMsg.what = 2;
                        try {
                            // 发送消息给request client
                            clientMessenger.send(toClientMsg);
                            Log.d(TAG, "clientMessenger send success");
                        } catch (RemoteException e) {
                            Log.e(TAG, "clientMessenger send fail");
                            throw new RuntimeException(e);
                        }
                        break;
                }
            }
        });
        // server返回binder对象给client
        return messenger.getBinder();
    }
}

客户端代码

通过bindService与服务端建立连接,连接成功后会获取到服务端的IBinder对象,然后构造出服务端的Messenger serverMessenger 对象,最后通过serverMessenger来send消息给服务端并进行通信,消息中携带的replyTo是用于服务端获取到客户端消息后给予回复。

package com.example.test.messenger;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.example.test.R;

public class MessengerActivity extends AppCompatActivity {

    private static final String TAG = "MessengerActivity";

    private ClientServiceConnection mClientServiceConnection;
    private Messenger clientMessenger;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);

        clientMessenger = new Messenger(new Handler(this.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Log.d(TAG, "clientMessenger msg.what = " + msg.what);
            }
        });

        Intent intent = new Intent();
        intent.setAction("messenger.action.test.message");
        intent.setPackage("com.example.test");
        mClientServiceConnection = new ClientServiceConnection();
        bindService(intent, mClientServiceConnection, Context.BIND_AUTO_CREATE);

        findViewById(R.id.btn_send_msg).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "click send msg to server");
                Message toServerMsg = Message.obtain();
                toServerMsg.what = 1;
                // 给server端设置reply的client端的传信者
                toServerMsg.replyTo = clientMessenger;
                Log.d(TAG, "clientSend = " + clientMessenger);
                // 注意不可以传递非parcel的对象,例如toServerMsg.obj = "11111";是不被允许的 ,只能给obj赋值为parcel类型才是可以的
                Bundle bundle = new Bundle();
                bundle.putString("bundle_key", "123456");
                toServerMsg.setData(bundle);
                try {
                    serverMessenger.send(toServerMsg);
                    Log.d(TAG, "serverMessenger send success");
                } catch (RemoteException e) {
                    Log.e(TAG, "serverMessenger send fail");
                    throw new RuntimeException(e);
                }

            }
        });
    }

    private Messenger serverMessenger;

    private class ClientServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");
            serverMessenger = new Messenger(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected");
        }
    }
}

AndroidManifest.xml配置

<service
            android:name=".messenger.MessengerService"
            android:exported="true">
            <intent-filter>
                <action android:name="messenger.action.test.message" />
            </intent-filter>
        </service>
        <activity
            android:name=".messenger.MessengerActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

日志输出

关于使用Messenger双向通信时的打印日志如下所示

04-22 17:24:12.170 16151 16151 D MessengerActivity: onServiceConnected
04-22 17:24:57.742 16151 16151 D MessengerActivity: click send msg to server
04-22 17:24:57.742 16151 16151 D MessengerActivity: clientSend = android.os.Messenger@a7d382e
04-22 17:24:57.743 16151 16151 D MessengerActivity: serverMessenger send success
04-22 17:24:57.752 16151 16151 D MessengerService: MessengerService handleMessage msg.what = 1
04-22 17:24:57.752 16151 16151 D MessengerService: bundleValue = 123456
04-22 17:24:57.752 16151 16151 D MessengerService: clientMessenger = android.os.Messenger@a7d382e
04-22 17:24:57.753 16151 16151 D MessengerService: clientMessenger send success
04-22 17:24:57.753 16151 16151 D MessengerActivity: clientMessenger msg.what = 2
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值