一句话说透Android里面的进程间通信方式

用大白话解释 Android 进程间通信(IPC)的方式

一句话总结:
进程间通信就像"不同办公室之间传纸条",Android 提供了多种传纸条的方式,各有优缺点,用对场景是关键!


1. Intent(最基础的方式)

  • 场景:启动其他应用的页面(Activity)或服务(Service)。

  • 原理:通过系统"邮局"传递简单数据。

  • 示例

    kotlin 复制代码
    // 发送方(App A)  
    val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))  
    startActivity(intent)  
    
    // 接收方(App B 的 Activity)  
    override fun onCreate(savedInstanceState: Bundle?) {  
        val data = intent?.data // 获取传递的数据  
    }  
  • 优点:简单易用,系统级支持。

  • 缺点:只能传简单数据,不能跨进程频繁通信。


2. Bundle(Intent 的扩展包)

  • 场景:在 Intent 基础上传递复杂数据(对象、文件描述符)。

  • 原理:把数据打包成"包裹",通过 Intent 传递。

  • 示例

    scss 复制代码
    val bundle = Bundle().apply {  
        putString("key", "value")  
        putParcelable("user", User("Alice"))  
    }  
    intent.putExtras(bundle)  
  • 限制 :传输的对象必须实现 ParcelableSerializable


3. Binder(Android 的 IPC 核心)

  • 场景:跨进程调用服务(如系统服务、自定义后台服务)。

  • 原理:通过"代理模式"实现远程方法调用(类似打电话)。

  • 核心组件

    • AIDL(Android Interface Definition Language) :定义接口,自动生成 Binder 代码。
    • Service:实现接口,处理远程调用。
  • 示例

    kotlin 复制代码
    // AIDL 文件(IRemoteService.aidl)  
    interface IRemoteService {  
        int add(int a, int b);  
    }  
    
    // 服务端实现  
    class RemoteService : Service() {  
        private val binder = object : IRemoteService.Stub() {  
            override fun add(a: Int, b: Int) = a + b  
        }  
        override fun onBind(intent: Intent) = binder  
    }  
    
    // 客户端调用  
    val serviceConnection = object : ServiceConnection {  
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {  
            val remoteService = IRemoteService.Stub.asInterface(service)  
            val result = remoteService.add(1, 2) // 跨进程调用  
        }  
    }  
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)  
  • 优点:高效,支持复杂交互。

  • 缺点:代码较复杂,需处理多线程和异常。


4. Messenger(基于 Binder 的简化版)

  • 场景:跨进程发送消息(串行处理,适合简单通信)。

  • 原理:通过 Handler 传递 Message,底层基于 Binder。

  • 示例

    kotlin 复制代码
    // 服务端  
    class MessengerService : Service() {  
        private val handler = object : Handler(Looper.getMainLooper()) {  
            override fun handleMessage(msg: Message) {  
                // 处理客户端消息  
                val reply = Message.obtain()  
                reply.what = 1  
                reply.arg1 = msg.arg1 + msg.arg2  
                msg.replyTo.send(reply)  
            }  
        }  
        private val messenger = Messenger(handler)  
        override fun onBind(intent: Intent) = messenger.binder  
    }  
    
    // 客户端  
    val clientMessenger = Messenger(Handler(Looper.getMainLooper()))  
    val message = Message.obtain().apply {  
        what = 1  
        arg1 = 10  
        arg2 = 20  
        replyTo = clientMessenger  
    }  
    serviceMessenger.send(message)  
  • 优点:比直接 Binder 简单,适合单向或简单双向通信。

  • 缺点:不能并行处理消息。


5. ContentProvider(数据共享的"公共仓库")

  • 场景:跨进程共享结构化数据(如通讯录、媒体库)。

  • 原理 :通过 URI 暴露数据接口,其他应用通过 ContentResolver 访问。

  • 示例

    kotlin 复制代码
    // 定义 ContentProvider  
    class MyProvider : ContentProvider() {  
        override fun query(uri: Uri, ...): Cursor {  
            // 根据 URI 查询数据  
            return database.query(...)  
        }  
    }  
    
    // 客户端查询  
    val cursor = contentResolver.query(  
        Uri.parse("content://com.example.provider/data"),  
        null, null, null, null  
    )  
  • 优点:标准化数据访问,支持权限控制。

  • 缺点:适合结构化数据,不适合高频或复杂操作。


6. 文件 & SharedPreferences(原始方式)

  • 场景:跨进程读写同一文件或配置。

  • 原理:通过文件系统共享数据(需处理并发)。

  • 示例

    scss 复制代码
    // 写入文件  
    File("/sdcard/shared.txt").writeText("Hello")  
    
    // 读取文件  
    val content = File("/sdcard/shared.txt").readText()  
  • 优点:简单,无需复杂配置。

  • 缺点:效率低,并发易出错,安全性差。


7. Socket(网络通信)

  • 场景:跨设备或本机进程间网络通信。

  • 原理:通过 TCP/IP 或本地 Socket 传输数据。

  • 示例

    scss 复制代码
    // 服务端  
    val serverSocket = ServerSocket(8080)  
    val socket = serverSocket.accept()  
    val input = socket.getInputStream().bufferedReader().readLine()  
    
    // 客户端  
    val socket = Socket("localhost", 8080)  
    socket.getOutputStream().bufferedWriter().write("Hello")  
  • 优点:跨网络通用,灵活性高。

  • 缺点:实现复杂,性能开销大。


总结:如何选择 IPC 方式?

场景 推荐方式
启动其他应用页面 Intent
跨进程方法调用(复杂接口) Binder/AIDL
简单消息传递(单向/双向) Messenger
结构化数据共享(如数据库) ContentProvider
临时数据共享(非高频) 文件/SharedPreferences
跨设备或网络通信 Socket

注意事项(避坑指南)

  1. 权限控制 :跨进程访问需声明权限(如 ContentProvider 的 android:permission)。
  2. 性能优化:高频通信优先选 Binder,避免用文件或 Socket。
  3. 安全性 :防止恶意应用窃取数据(如 Intent 添加 FLAG_GRANT_READ_URI_PERMISSION)。
  4. 版本兼容:不同 Android 版本对 IPC 的限制不同(如后台 Service 限制)。

口诀
"Intent 传页 Messenger 信,
Binder 复杂 AIDL 定,
文件共享效率低,ContentProvider 管数据,
Socket 跨网也能行,选对方式最要紧!"

相关推荐
小成很成5 小时前
mysql 8.0.21 升级 mysql 8.0.45(经过生产环境验证)
android·mysql·adb
阿里嘎多学长9 小时前
2026-08-24 GitHub 热点项目精选
开发语言·程序员·github·代码托管
kyriewen9 小时前
我拿 4 个真实前端任务试了 GLM-5.3 Flash:代码一遍跑通,账单 4 分钱
前端·程序员·ai编程
虎王物联9 小时前
PHP实现MQTT消息处理:物联网设备数据接收与指令下发
android·物联网·php
我命由我1234510 小时前
Android 开发 - 获取当前设备屏幕的旋转角度
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
程序员-Benothing11 小时前
MySQL 索引下推是什么?——深入理解 ICP 原理与实践
android·数据库·mysql
这个DBA有点耶11 小时前
MySQL主从延迟的“最后一公里”:如何把延迟压到极限
数据库·程序员·架构
怀化纱厂球迷12 小时前
百度地图--android接入百度地图导航
android
AFinalStone12 小时前
Android 7系统无障碍服务(四)AccessibilityEvent 的产生与投递
android·无障碍服务