持续创作,加速成长!这是我参与「掘金日新计划 · 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步骤:
-
服务端进程:
在服务端创建Service处理客户端的连接请求。
创建Handler处理客户端的消息,并通过它创建Messenger对象。 (Messenger对象的作用是将客户端发送的消息传递给Handler处理)
在Service的onBind中返回这个Messenger的底层Binder。
响应客户端:
通过Message的replyTo获得服务端的Messenger
-
客户端进程:
绑定服务端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()
}
}