Android Messenger跨进程通信相关学习总结

Messenger是什么?

  • Messenger是对AIDL的封装,AIDL又是基于Binder机制实现的,使用Messenger能使我们更简单的实现进程间通信
  • 优势在于我们可以免于自己去定义.aidl文件,使用系统中提前定义好的Messenger.aidl
  • Messenger通常和Message、Handler一起使用
    Messenger中封装了Handler,通过Messenger.send(Message)最终也就是调用了Handler.sendMessage()
    在这里插入图片描述

Messenger流程

  • 在客户端中启动一个服务,可以得到这个服务的serviceMessenger,然后通过serviceMessenger发送当前客户端的clientMessenger给服务端,这时候就实现了双向绑定。

Messenger用法

  • 将MyService放入单独的进程中android:process=":remote"
        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":remote" />
  • 如何跨应用启动service
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.vision.mymessager", "com.vision.mymessager.MyService"));
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
  • MainActivity中
    • MainActivity可以通Intent传递信息到另一个进程的Service
    • bindService调用后,启动计时器Counting,这时候并没有回调信息到主进程(MainActivity),当点击事件触发后,MainActivity发送Message并附加clientMessenger到Service,Service接收到消息后,保存clientMessenger到当前进程中,然后计时器中的clientMessenger不为空,开始向主进程发送消息
package com.vision.mymessager

import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.*
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity

private const val TAG = "MainActivity"

class MainActivity : AppCompatActivity() {


    private var handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                MSG_FROM_SERVICE -> {
                    Log.d(TAG, "handleMessage: ${msg.data.getString(MSG_KEY)}")
                }
            }
        }
    }
    private var clientMessenger: Messenger = Messenger(handler)
    private var serviceMessenger: Messenger? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val intent = Intent(this, MyService::class.java)
        intent.putExtra(MSG_KEY, "test")
        bindService(intent, object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                serviceMessenger = Messenger(service)
            }

            override fun onServiceDisconnected(name: ComponentName?) {
                serviceMessenger = null
            }
        }, BIND_AUTO_CREATE)
    }

    fun onClick(view: View) {
        val msg = Message.obtain()
        val bundle = Bundle()
        bundle.putString("key", "msg from client")
        msg.what = MSG_FROM_CLIENT
        msg.data = bundle
        msg.replyTo = clientMessenger
        serviceMessenger?.send(msg)
    }
}
  • Myservice
package com.vision.mymessager

import android.app.Service
import android.content.Intent
import android.os.*
import android.util.Log
import java.util.concurrent.ScheduledThreadPoolExecutor
import java.util.concurrent.TimeUnit

private const val TAG = "MyService"
const val MSG_FROM_SERVICE = 0
const val MSG_FROM_CLIENT = 1
const val MSG_KEY = "msg_key"

class MyService : Service() {

    private val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                MSG_FROM_CLIENT -> {
                    Log.d(TAG, "handleMessage: ${msg.data.getString(MSG_KEY)}")
                    //通过clientMessenger发送消息到client
                    val bundle = Bundle()
                    bundle.putString(MSG_KEY, "msg from service")
                    msg.what = MSG_FROM_SERVICE
                    msg.data = bundle
                    clientMessenger = msg.replyTo
                    clientMessenger?.send(msg)
                }
            }
        }
    }

	//保存客户端的clientMessenger,用于向客户端发送消息
    private var clientMessenger: Messenger? = null

    private var serviceMessenger = Messenger(handler)

    override fun onBind(intent: Intent): IBinder {
        val value = intent.getStringExtra(MSG_KEY)
        Log.d(TAG, "onBind: $value")
        return serviceMessenger.binder
    }

    override fun onCreate() {
        super.onCreate()
        counting()
    }

	//使用线程池,实现一个计时器
    private var threadPool = ScheduledThreadPoolExecutor(1)

	//计时器
    private fun counting() {
        Log.d(TAG, "counting: ")
        val bundle = Bundle()
        var i = 0
        threadPool.scheduleAtFixedRate({
            Log.d(TAG, "onBind: $i")
            bundle.putString(MSG_KEY, "${i++}")
            val msg = Message.obtain()
            msg.what = MSG_FROM_SERVICE
            msg.data = bundle
            clientMessenger?.send(msg)
        }, 0, 1000, TimeUnit.MILLISECONDS)
    }

    override fun onDestroy() {
        super.onDestroy()
        threadPool.shutdownNow()
        handler.removeCallbacksAndMessages(null)
    }
}

Messenger源码

  • Messenger构造方法一(创建clientMessenger)
    调用了Handler的getIMessenger
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
  • Messenger构造方法二(得到serviceMessenger)
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
  • 在Handler中有如下代码
    • getIMessenger方法获取MessengerImpl
    • MessengerImpl又继承自IMessenger.Stub,并且实现了send方法,send方法最终调用的是Handler.sendMessage
    @UnsupportedAppUsage
    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值