IPC进程间通信

146 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

Android开发艺术探索 阅读笔记

进程间通信的几种方式:

  • Intent+Bundle
  • 共享文件
  • Binder
  • ContentProvider
  • 网络通信socket

1. Intent+Bundle

三大组件(Activity、Service、BroadcastReceiver)都支持在Intent中传递Bundle数据,且Bundle实现了Parcelable接口,使得它可以很方便地在不同的进程间传输。传输的数据必须能被序列化,如基本类型。

巧妙规避IPC:当需要将进程A计算的结果传递给进程B时,如果能够在进程B中进行计算,则免去了IPC。直接通过进程A启动进程B的一个Service进行计算,得到结果后启动目标组件。

2. 文件共享

两个进程通过读写同一个文件来共享数据。应避免并发读写,并发读写读到的数据可能不是最新的,可以考虑使用线程同步来限制多个进程的写操作。多进程读写SharePreferences是不可靠的。

3. 信使Messenger

轻量级的IPC。底层是AIDL,对AIDL做了封装。一次处理一个请求,不用考虑线程同步的问题。

实现Messenger步骤:

  1. 服务端进程:

    在服务端创建Service处理客户端的连接请求。

    创建Handler处理客户端的消息,并通过它创建Messenger对象。 (Messenger对象的作用是将客户端发送的消息传递给Handler处理)

    在Service的onBind中返回这个Messenger的底层Binder。

    响应客户端:

    通过Message的replyTo获得服务端的Messenger

  2. 客户端进程:

    绑定服务端Service。

    用服务端返回的IBinder创建Messenger。

    通过Messenger向服务端发送消息Message。

    获得服务端的响应:

    创建Handler用来处理服务端返回的消息,并创建Messenger

    把Messenger通过Message的replyTo参数传递给服务端

服务端代码:

//1. 创建客户端Service
class MessengerServerService : Service() {
​
    //4. 返回Messenger对象的底层Binder
    override fun onBind(intent: Intent): IBinder {
        return mMessenger.binder
    }
​
    companion object {
        private val TAG = "MessengerServerService"
​
        //2. 创建Handler进行消息处理
        private class MessengerHandler : Handler() {
            override fun handleMessage(msg: Message) {
                when (msg.what) {
                    Constant.MSG.FROM_CLIENT -> {
                        Log.i(TAG, "receiver msg from Client:${msg.data.getString("msg")}")
                        //5. 获得客户端的Messenger响应客户端
                        val client = msg.replyTo
                        val replyMessage = Message.obtain(null, Constant.MSG.FROM_SERVER)
                        val bundle = Bundle()
                        bundle.putString("reply", "你的消息我已经收到啦啦啦,稍后再回复你喽")
                        replyMessage.data = bundle
                        client.send(replyMessage)       //发送消息
                    }
                    else ->
                        super.handleMessage(msg)
                }
            }
        }
    }
​
    //3. 创建Messenger对象
    private val mMessenger = Messenger(MessengerHandler())
}

客服端代码:

class MessengerClientActivity : BaseActivity() {
    private val TAG = "MessengerClientActivity"
    private var mService: Messenger? = null
​
    override val layoutId: Int
        get() = R.layout.activity_messenger_client
​
    override fun initViews() {
      //连接Service
        bindService(
            Intent(this, MessengerServerService::class.java),
            mConnection,
            Context.BIND_AUTO_CREATE
        )
    }
​
    private val mConnection = object : ServiceConnection {
        override fun onServiceDisconnected(name: ComponentName?) {
        }
​
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            mService = Messenger(service)
            val msg = Message.obtain(null, Constant.MSG.FROM_CLIENT)
            val data = Bundle();
            data.putString("msg", "hello,this is client.");
            msg.data = data
            msg.replyTo = mGetReplyMessenger
            mService?.send(msg)
        }
    }
​
    //接受服务端消息的messenger
    private val messengerHandler = object : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                Constant.MSG.FROM_SERVER -> {
                    Log.i(TAG, "receiver msg from Service:${msg.data.getString("reply")}")
                }
                else ->
                    super.handleMessage(msg)
            }
        }
    }
    private val mGetReplyMessenger = Messenger(messengerHandler)
​
​
    override fun onDestroy() {
        unbindService(mConnection)
        super.onDestroy()
    }
}