Blog #199: 跨进程通信IPC机制
难度:⭐⭐⭐⭐⭐标签:IPC Binder 什么是IPC?Android有哪些跨进程通信方式?如何实现高效安全的跨进程通信?**IPC(Inter-Process Communication,进程间通信)**是指不同进程间交换数据的机制。Android基于Linux,提供多种IPC方式:Binder(核心机制)、AIDL(接口定义)、Messenger(轻量级)、ContentProvider(数
·
Blog #199: 跨进程通信IPC机制
难度:⭐⭐⭐⭐⭐
标签:Android IPC AIDL Binder 跨进程
🎯 核心问题
什么是IPC?Android有哪些跨进程通信方式?如何实现高效安全的跨进程通信?
💡 核心概念
**IPC(Inter-Process Communication,进程间通信)**是指不同进程间交换数据的机制。Android基于Linux,提供多种IPC方式:Binder(核心机制)、AIDL(接口定义)、Messenger(轻量级)、ContentProvider(数据共享)、Socket(网络通信)。
Binder机制核心
Binder是Android特有的IPC机制,基于客户端-服务端模型,通过内核驱动实现高效数据传输(只需一次拷贝)。
📝 详细说明
1. 多进程基础
1.1 配置多进程
<!-- AndroidManifest.xml -->
<manifest>
<application>
<!-- 主进程 -->
<activity android:name=".MainActivity" />
<!-- 独立进程 -->
<activity
android:name=".RemoteActivity"
android:process=":remote" />
<!-- 全局进程 -->
<service
android:name=".RemoteService"
android:process="com.example.app.remote" />
<!-- 私有进程(默认) -->
<service
android:name=".LocalService"
android:process=":local" />
</application>
</manifest>
1.2 多进程影响
class ProcessDemo : Application() {
companion object {
var counter = 0 // 每个进程独立的静态变量
}
override fun onCreate() {
super.onCreate()
counter++
val processName = getCurrentProcessName()
Log.d("Process", "进程: $processName, Counter: $counter")
// 不同进程的counter互不影响
}
private fun getCurrentProcessName(): String {
val pid = android.os.Process.myPid()
val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
am.runningAppProcesses?.forEach { processInfo ->
if (processInfo.pid == pid) {
return processInfo.processName
}
}
return "Unknown"
}
}
class MultiProcessIssues : AppCompatActivity() {
fun demonstrateIssues() {
// 问题1: 静态变量失效
ProcessDemo.counter = 100
Log.d("Issues", "主进程counter: ${ProcessDemo.counter}")
// 其他进程的counter不受影响
// 问题2: SharedPreferences不同步
val prefs = getSharedPreferences("data", Context.MODE_PRIVATE)
prefs.edit().putString("key", "value").apply()
// 其他进程可能读取不到最新值
// 问题3: Application多次创建
// 每个进程都会创建独立的Application实例
// 问题4: 文件共享问题
// 多进程同时写入同一文件可能冲突
}
}
2. AIDL实现
2.1 定义AIDL接口
// IBookManager.aidl
package com.example.app;
import com.example.app.Book;
interface IBookManager {
List<Book> getBookList();
void addBook(in Book book);
void registerListener(IOnNewBookArrivedListener listener);
void unregisterListener(IOnNewBookArrivedListener listener);
}
// Book.aidl
package com.example.app;
parcelable Book;
// IOnNewBookArrivedListener.aidl
package com.example.app;
import com.example.app.Book;
interface IOnNewBookArrivedListener {
void onNewBookArrived(in Book newBook);
}
2.2 数据类实现
@Parcelize
data class Book(
val bookId: Int,
val bookName: String,
val author: String,
val price: Double
) : Parcelable
2.3 Service端实现
class BookManagerService : Service() {
private val bookList = CopyOnWriteArrayList<Book>()
private val listenerList = RemoteCallbackList<IOnNewBookArrivedListener>()
private val binder = object : IBookManager.Stub() {
override fun getBookList(): List<Book> {
// 延迟模拟
SystemClock.sleep(2000)
return bookList
}
override fun addBook(book: Book) {
bookList.add(book)
Log.d("Service", "添加书籍: ${book.bookName}")
// 通知所有监听器
notifyNewBook(book)
}
override fun registerListener(listener: IOnNewBookArrivedListener?) {
listenerList.register(listener)
Log.d("Service", "注册监听器,当前数量: ${listenerList.registeredCallbackCount}")
}
override fun unregisterListener(listener: IOnNewBookArrivedListener?) {
listenerList.unregister(listener)
Log.d("Service", "注销监听器,当前数量: ${listenerList.registeredCallbackCount}")
}
}
override fun onCreate() {
super.onCreate()
// 初始化数据
bookList.add(Book(1, "Android开发艺术探索", "任玉刚", 89.0))
bookList.add(Book(2, "Kotlin实战", "Dmitry Jemerov", 79.0))
}
override fun onBind(intent: Intent): IBinder {
// 权限检查
val permission = checkCallingOrSelfPermission("com.example.app.BOOK_SERVICE")
if (permission == PackageManager.PERMISSION_DENIED) {
return null!!
}
return binder
}
private fun notifyNewBook(book: Book) {
val count = listenerList.beginBroadcast()
try {
for (i in 0 until count) {
val listener = listenerList.getBroadcastItem(i)
try {
listener?.onNewBookArrived(book)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
} finally {
listenerList.finishBroadcast()
}
}
}
2.4 Client端实现
class BookManagerActivity : AppCompatActivity() {
private lateinit var binding: ActivityBookManagerBinding
private var bookManager: IBookManager? = null
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
bookManager = IBookManager.Stub.asInterface(service)
isBound = true
// 设置死亡监听
service.linkToDeath(deathRecipient, 0)
// 加载书籍列表
loadBooks()
// 注册监听器
bookManager?.registerListener(bookArrivedListener)
}
override fun onServiceDisconnected(name: ComponentName) {
bookManager = null
isBound = false
}
}
// Binder死亡监听
private val deathRecipient = object : IBinder.DeathRecipient {
override fun binderDied() {
Log.d("Client", "Binder died")
bookManager?.asBinder()?.unlinkToDeath(this, 0)
bookManager = null
// 重新连接
bindServiceSafely()
}
}
// 新书到达监听器
private val bookArrivedListener = object : IOnNewBookArrivedListener.Stub() {
override fun onNewBookArrived(newBook: Book) {
// 在Binder线程池调用,需要切换到主线程
runOnUiThread {
Log.d("Client", "新书到达: ${newBook.bookName}")
Toast.makeText(
this@BookManagerActivity,
"新书: ${newBook.bookName}",
Toast.LENGTH_SHORT
).show()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBookManagerBinding.inflate(layoutInflater)
setContentView(binding.root)
setupClickListeners()
bindServiceSafely()
}
private fun setupClickListeners() {
binding.btnGetBooks.setOnClickListener {
loadBooks()
}
binding.btnAddBook.setOnClickListener {
addBook()
}
}
private fun bindServiceSafely() {
val intent = Intent(this, BookManagerService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
private fun loadBooks() {
if (!isBound) return
// AIDL调用是同步的,需要在子线程
lifecycleScope.launch(Dispatchers.IO) {
try {
val books = bookManager?.bookList ?: emptyList()
withContext(Dispatchers.Main) {
displayBooks(books)
}
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
private fun displayBooks(books: List<Book>) {
val text = books.joinToString("\n") {
"${it.bookName} - ${it.author} (¥${it.price})"
}
binding.tvBooks.text = text
}
private fun addBook() {
if (!isBound) return
val newBook = Book(
bookId = (Math.random() * 1000).toInt(),
bookName = "新书${System.currentTimeMillis() % 1000}",
author = "作者",
price = 99.0
)
lifecycleScope.launch(Dispatchers.IO) {
try {
bookManager?.addBook(newBook)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
override fun onDestroy() {
super.onDestroy()
if (isBound) {
// 注销监听器
bookManager?.unregisterListener(bookArrivedListener)
unbindService(connection)
isBound = false
}
}
}
3. Messenger实现
// Service端(轻量级IPC)
class MessengerService : Service() {
companion object {
const val MSG_FROM_CLIENT = 1
const val MSG_FROM_SERVICE = 2
}
private class ServiceHandler(
context: Context
) : Handler(Looper.getMainLooper()) {
private val appContext = context.applicationContext
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_FROM_CLIENT -> {
val data = msg.data.getString("data")
Log.d("Service", "收到客户端消息: $data")
// 回复客户端
msg.replyTo?.send(
Message.obtain(null, MSG_FROM_SERVICE).apply {
data = Bundle().apply {
putString("reply", "收到: $data")
}
}
)
}
}
}
}
private val messenger = Messenger(ServiceHandler(this))
override fun onBind(intent: Intent): IBinder {
return messenger.binder
}
}
// Client端
class MessengerClient : AppCompatActivity() {
private var serviceMessenger: Messenger? = null
private val clientMessenger = Messenger(ClientHandler(this))
private class ClientHandler(activity: MessengerClient) : Handler(Looper.getMainLooper()) {
private val activityRef = WeakReference(activity)
override fun handleMessage(msg: Message) {
when (msg.what) {
MessengerService.MSG_FROM_SERVICE -> {
val reply = msg.data.getString("reply")
Log.d("Client", "收到服务端回复: $reply")
}
}
}
}
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
serviceMessenger = Messenger(service)
sendMessage("Hello")
}
override fun onServiceDisconnected(name: ComponentName) {
serviceMessenger = null
}
}
override fun onStart() {
super.onStart()
Intent(this, MessengerService::class.java).also {
bindService(it, connection, Context.BIND_AUTO_CREATE)
}
}
override fun onStop() {
super.onStop()
unbindService(connection)
}
private fun sendMessage(text: String) {
val msg = Message.obtain(null, MessengerService.MSG_FROM_CLIENT).apply {
data = Bundle().apply {
putString("data", text)
}
replyTo = clientMessenger
}
try {
serviceMessenger?.send(msg)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
4. ContentProvider跨进程
class BookProvider : ContentProvider() {
companion object {
const val AUTHORITY = "com.example.app.provider"
val BOOK_CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY/book")
const val BOOK_URI_CODE = 0
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
addURI(AUTHORITY, "book", BOOK_URI_CODE)
}
}
override fun onCreate(): Boolean {
// 初始化
return true
}
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? {
// 查询数据
return when (uriMatcher.match(uri)) {
BOOK_URI_CODE -> {
// 返回Cursor
null
}
else -> null
}
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
// 插入数据
return null
}
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int {
// 更新数据
return 0
}
override fun delete(
uri: Uri,
selection: String?,
selectionArgs: Array<out String>?
): Int {
// 删除数据
return 0
}
override fun getType(uri: Uri): String? {
return null
}
}
5. IPC方式对比
object IPCComparison {
data class IPCMethod(
val name: String,
val complexity: Complexity,
val dataType: String,
val useCase: String,
val pros: List<String>,
val cons: List<String>
)
enum class Complexity {
LOW, MEDIUM, HIGH
}
val methods = listOf(
IPCMethod(
"Bundle",
Complexity.LOW,
"基本类型、Parcelable",
"Activity/Service传参",
listOf("简单", "官方支持"),
listOf("不支持实时通信", "数据大小限制")
),
IPCMethod(
"文件共享",
Complexity.LOW,
"任意数据",
"不要求实时性的数据共享",
listOf("简单", "支持大数据"),
listOf("不适合高并发", "需要同步")
),
IPCMethod(
"Messenger",
Complexity.MEDIUM,
"Message",
"轻量级IPC,低并发",
listOf("简单易用", "自动排队"),
listOf("串行处理", "不支持RPC")
),
IPCMethod(
"AIDL",
Complexity.HIGH,
"基本类型、Parcelable、List、Map",
"复杂跨进程调用",
listOf("功能强大", "支持并发"),
listOf("复杂", "需要处理线程同步")
),
IPCMethod(
"ContentProvider",
Complexity.MEDIUM,
"Cursor",
"一对多数据共享",
listOf("标准化", "支持多进程"),
listOf("受限于表格模型", "主要用于数据")
),
IPCMethod(
"Socket",
Complexity.HIGH,
"字节流",
"网络通信",
listOf("功能强大", "跨设备"),
listOf("复杂", "性能开销大")
)
)
}
⚡ 关键要点
- Binder机制 - Android IPC核心,一次拷贝,性能优秀
- AIDL - 复杂跨进程通信首选,支持并发和回调
- Messenger - 轻量级IPC,串行处理,适合低并发
- 线程安全 - AIDL方法在Binder线程池调用,需处理线程同步
- 生命周期 - 注意Service连接管理和Binder死亡监听
🔗 相关知识点
更多推荐


所有评论(0)