一句话说透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 跨网也能行,选对方式最要紧!"

相关推荐
alexhilton1 小时前
为什么你的App总是忘记所有事情
android·kotlin·android jetpack
皮皮林5511 小时前
90 后程序员辞职搞灰产,不到一年获利超 700 万,结局很刑!
程序员
AirDroid_cn4 小时前
OPPO手机怎样被其他手机远程控制?两台OPPO手机如何相互远程控制?
android·windows·ios·智能手机·iphone·远程工作·远程控制
尊治4 小时前
手机电工仿真软件更新了
android
SimonKing6 小时前
告别传统读写!RandomAccessFile让你的Java程序快人一步
java·后端·程序员
大模型开发7 小时前
Java开发者LLM实战——使用LangChain4j构建本地RAG系统
程序员·langchain·llm
xiangzhihong87 小时前
使用Universal Links与Android App Links实现网页无缝跳转至应用
android·ios
京东云开发者8 小时前
企业和个人基于业务知识和代码库增强的大模型生成代码实践
程序员
车载应用猿8 小时前
基于Android14的CarService 启动流程分析
android
没有了遇见9 小时前
Android 渐变色实现总结
android