Intent 和 binder

可以这样理解这句话:

Intent 是 Android 上层提供的“通信载体/请求描述”,真正跨进程通信时,底层靠的是 Binder IPC;而 Binder 为了提高效率,会通过 mmap 等方式在进程和内核之间建立一块映射内存区域,减少数据拷贝,所以有人说“物理层通过共享内存实现”。

但要注意:Intent 本身不是通信机制,Binder 才是通信机制


1. Intent 是什么?

Intent 可以理解为一个“消息对象”或者“请求对象”。

它里面描述了:

Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("name", "Tom");
startActivity(intent);

这个 Intent 表达的是:

我要启动 SecondActivity,并且传递一些参数。

Intent 常用于四大组件之间:

组件 使用方式
Activity startActivity(intent)
Service startService(intent) / bindService(intent)
BroadcastReceiver sendBroadcast(intent)
ContentProvider 通常通过 Uri + ContentResolver 间接访问

Intent 可以用于:

  1. 同一个 App 内部组件通信
  2. 不同 App 之间通信
  3. 应用和系统服务之间通信

例如调用系统相机:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);

这时就是 App 和其他 App/系统组件之间通信。


2. Intent 本身不负责通信

很多人容易误解:

Intent 是不是像 Socket 一样负责把数据发过去?

不是。

Intent 只是一个数据结构,类似于:

我要做什么?
目标是谁?
带了什么参数?

真正把这个请求从一个进程传给另一个进程的,是 Android 的 Binder 机制。


3. startActivity 背后的大致流程

比如你调用:

startActivity(intent);

表面上看是 Activity 启动另一个 Activity,实际上大致流程是:

App 进程
  |
  | startActivity(intent)
  |
  v
ActivityTaskManagerService / ActivityManagerService
  |
  | Binder IPC
  |
  v
目标 App 进程
  |
  v
启动目标 Activity

更具体一点:

你的 Activity
    |
    | startActivity(intent)
    |
    v
Instrumentation
    |
    v
ActivityTaskManagerService,系统进程中
    |
    | 判断目标 Activity、权限、任务栈等
    |
    v
如果目标进程不存在,先启动进程
    |
    v
通过 Binder 通知目标进程创建 Activity
    |
    v
目标 Activity.onCreate()

所以,两个 Activity 即使在不同 App 中,也不是直接通信,而是通过系统服务中转。


4. Binder 是什么?

Binder 是 Android 中最核心的跨进程通信机制,简称 IPC:

IPC = Inter-Process Communication

Android 中很多系统服务都基于 Binder,例如:

  • ActivityManagerService
  • WindowManagerService
  • PackageManagerService
  • LocationManagerService
  • InputMethodManagerService
  • MediaService

App 和系统服务交互,基本都要经过 Binder。

例如:

startActivity()
getSystemService()
bindService()
sendBroadcast()
ContentResolver.query()

底层都可能涉及 Binder 通信。


5. 为什么需要 Binder?

Android 中每个 App 通常运行在独立进程中。

例如:

微信进程
支付宝进程
系统服务进程
你的 App 进程

进程之间的内存是隔离的:

进程 A 不能直接访问进程 B 的内存

所以如果你的 App 想让系统启动一个 Activity,不能直接改系统进程的数据,只能通过某种 IPC 机制告诉系统。

Android 选择 Binder 作为主要 IPC 机制。


6. Intent 和 Binder 的关系

可以这样理解:

Intent 是上层消息内容
Binder 是底层传输通道

类似寄快递:

Intent = 快递包裹里的物品和说明
Binder = 快递运输系统
AMS/ATMS = 快递中转站
目标组件 = 收件人

比如:

Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("age", 18);
startActivity(intent);

这个 Intent 会被序列化成底层可以传输的数据,然后通过 Binder 发送给系统服务,系统服务再通知目标进程。


7. Intent 数据怎么通过 Binder 传递?

Intent 实现了 Parcelable 接口。

public class Intent implements Parcelable

Parcelable 是 Android 专门为 Binder IPC 设计的序列化机制。

当 Intent 需要跨进程传输时,会被写入 Parcel

Intent
  |
  v
Parcel
  |
  v
Binder 驱动
  |
  v
目标进程
  |
  v
反序列化成 Intent

大致过程:

发送方进程中的 Intent 对象
        |
        | writeToParcel()
        v
Parcel 数据
        |
        | Binder IPC
        v
接收方进程
        |
        | createFromParcel()
        v
新的 Intent 对象

注意:

目标进程拿到的不是原来那个 Intent 对象,而是反序列化后的新对象。


8. “物理层通过共享内存实现”怎么理解?

这句话需要稍微严谨一点。

Binder 通信不是简单地说“两个进程直接共享一块内存”。实际上 Binder 的核心包括:

  1. 用户空间的 Binder 调用
  2. 内核空间的 Binder 驱动
  3. mmap 映射的 Binder 缓冲区
  4. 数据拷贝和对象引用管理

传统 IPC,比如普通管道、Socket,可能需要多次数据拷贝:

发送进程用户空间
    -> 内核空间
    -> 接收进程用户空间

可能会发生两次拷贝。

Binder 为了提高效率,会让接收方进程通过 mmap 映射一块内核缓冲区。数据传输时,大致可以理解为:

发送进程用户空间
    -> Binder 内核缓冲区,接收进程可映射访问
    -> 接收进程读取

所以 Binder 通常被称为“一次拷贝”。

更通俗地说:

普通方式:
A 把数据复制给内核,内核再复制给 B。

Binder:
A 把数据复制到 Binder 驱动管理的缓冲区,
B 可以通过映射区域读取这份数据,
减少了一次拷贝。

所以“物理层通过共享内存实现”可以理解为:

Binder 底层使用内核驱动和内存映射机制,让进程之间通过一块受内核管理的映射缓冲区高效传输数据。

但不要理解成:

A 进程和 B 进程随便共享一块普通内存,互相直接读写。

不是这样。

Binder 的共享/映射内存是受 Binder 驱动严格管理的。


9. Intent 跨进程传递的完整理解

以启动另一个 App 的 Activity 为例:

Intent intent = new Intent();
intent.setComponent(new ComponentName(
        "com.example.target",
        "com.example.target.TargetActivity"
));
intent.putExtra("msg", "hello");
startActivity(intent);

大致流程:

你的 App 进程
  |
  | 1. 创建 Intent
  |
  | 2. 调用 startActivity()
  |
  | 3. Intent 被写入 Parcel
  |
  | 4. 通过 Binder 发送给系统服务 ATMS/AMS
  v
系统进程
  |
  | 5. 解析 Intent,查找目标 Activity
  | 6. 做权限检查、任务栈处理
  | 7. 如果目标进程未启动,先 fork 目标进程
  |
  | 8. 通过 Binder 通知目标 App 进程启动 Activity
  v
目标 App 进程
  |
  | 9. 从 Parcel 还原 Intent
  | 10. 创建 Activity
  | 11. 调用 onCreate()
  v

TargetActivity.onCreate()

目标 Activity 中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String msg = getIntent().getStringExtra("msg");
}

这里的 getIntent() 拿到的是经过 Binder/Parcel 传过来的数据。


10. 为什么 Intent 传大数据会出问题?

因为 Intent 通过 Binder 传输,而 Binder 的事务缓冲区是有限制的。

如果你这样做:

Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("bitmap", largeBitmap);
startActivity(intent);

可能会报:

TransactionTooLargeException

原因是:

Intent extras 太大,超过 Binder 事务大小限制。

常见限制一般约为 1MB 左右,但不同版本和场景会有差异。

所以 Intent 不适合传大数据。


11. 大数据应该怎么传?

不要直接通过 Intent 传大对象,例如:

  • 大 Bitmap
  • 大 List
  • 大 JSON
  • 大 byte[]
  • 大文件内容

推荐做法:

方式一:传 id

Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("userId", 1001);
startActivity(intent);

目标页面再根据 userId 查询数据。


方式二:传 Uri

例如图片、文件:

Intent intent = new Intent(this, PreviewActivity.class);
intent.setData(imageUri);
startActivity(intent);

或者:

intent.putExtra(Intent.EXTRA_STREAM, imageUri);

实际文件通过文件系统或 ContentProvider 访问。


方式三:使用 ViewModel / Repository / 数据库 / 缓存

同一 App 内可以:

  • 数据库
  • 内存缓存
  • Repository
  • ViewModel
  • 单例管理器,谨慎使用

方式四:跨进程大数据用 ContentProvider / 文件 / AIDL + 共享内存

如果是跨进程大数据:

  • ContentProvider
  • 文件共享
  • MemoryFile
  • SharedMemory
  • ParcelFileDescriptor

更合适。


12. Binder 和共享内存的区别

严格来说,Binder 和共享内存是两类 IPC 思想:

方式 特点
Binder 面向对象、支持权限、安全身份、适合控制命令和小数据
共享内存 适合大数据、高性能数据交换
Socket 通用网络/本地通信
Pipe 简单字节流
ContentProvider 面向结构化数据共享

Binder 底层用了内存映射优化,但它不等同于普通共享内存。

所以更准确的说法是:

Android 中 Intent 跨进程传输依赖 Binder;Binder 底层通过内核驱动和 mmap 映射缓冲区来减少数据拷贝,提高 IPC 效率。


13. 一句话总结

可以这样理解:

Intent 是上层传递的消息内容;
Parcelable/Parcel 负责把 Intent 序列化;
Binder 负责跨进程传输;
Binder Driver 负责在内核中完成进程间数据转发;
mmap 映射缓冲区用于提高传输效率。

更简洁地说:

Intent 不是真正的通信通道,它只是通信数据;Android 组件之间真正跨进程通信靠 Binder。Binder 底层通过内核驱动和内存映射机制实现高效、安全的进程间通信。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇