Android Intent 知识总结
整理日期:2026-07-30
覆盖:显式/隐式 Intent、Intent Filter、PendingIntent、Flag、安全限制与现代 API
目录
- [1. 是什么](#1. 是什么)
- [2. 能启动什么](#2. 能启动什么)
- [3. 显式 vs 隐式](#3. 显式 vs 隐式)
- [4. Intent 核心字段](#4. Intent 核心字段)
- [5. Intent Filter 匹配规则](#5. Intent Filter 匹配规则)
- [6. 常用 Action / Category / Data](#6. 常用 Action / Category / Data)
- [7. 传递数据](#7. 传递数据)
- [8. 启动与结果回调](#8. 启动与结果回调)
- [9. Intent Flag](#9. Intent Flag)
- [10. PendingIntent](#10. PendingIntent)
- [11. 广播中的 Intent](#11. 广播中的 Intent)
- [12. 安全与高版本限制](#12. 安全与高版本限制)
- [13. 常见坑](#13. 常见坑)
- [14. 速查 Checklist](#14. 速查 Checklist)
- [15. 优缺点与选型](#15. 优缺点与选型)
- [16. 参考链接](#16. 参考链接)
1. 是什么
Intent 是 Android 组件间通信的消息对象,描述「要做什么」:
- 启动 Activity / Service
- 发送广播
- 携带 action、data、category、extras、component 等信息
系统根据 Intent 找到目标组件(解析匹配或显式指定)。
发送方 ── Intent ──→ 系统(AMS)──→ 目标组件
注意:Intent 不是通用 RPC;跨进程大数据、持续通信应使用 Binder / AIDL / ContentProvider 等。
2. 能启动什么
| 目标 | API | 说明 |
|---|---|---|
| Activity | startActivity / startActivityForResult(旧)/ Activity Result API |
可带 Flag、结果回传 |
| Service | startService / startForegroundService / bindService |
后台限制多,优先评估 WorkManager / FGS |
| BroadcastReceiver | sendBroadcast / sendOrderedBroadcast |
显式广播更安全 |
| 其他 App | 隐式 Intent 或显式指定包名/组件 | 受包可见性、exported 影响 |
3. 显式 vs 隐式
3.1 显式 Intent(Explicit)
明确指定目标组件(类名或 ComponentName),应用内首选。
kotlin
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra(EXTRA_ID, id)
}
startActivity(intent)
| 优点 | 匹配确定、安全、不受 Filter 干扰 |
| 缺点 | 需知道目标类;跨应用时耦合包名/组件名 |
3.2 隐式 Intent(Implicit)
不指定组件,靠 action + category + data 与 Manifest 中 intent-filter 匹配。
kotlin
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"))
startActivity(intent)
| 优点 | 解耦、可调起系统/其他 App(浏览器、分享、相机) |
| 缺点 | 可能匹配多个或零个;安全与可见性限制多 |
解析相关:
resolveActivity/queryIntentActivities:是否有处理器- 多个匹配时系统弹出选择器;可用
Intent.createChooser强制选择器
4. Intent 核心字段
| 字段 | 作用 |
|---|---|
| Component | 显式目标组件 |
| Action | 要执行的通用动作字符串 |
| Data | Uri(如 content://、https://、tel:) |
| Type | MIME(如 image/*、application/pdf);可与 Data 联动 |
| Category | 额外类别(如 CATEGORY_DEFAULT、LAUNCHER) |
| Extras | Bundle 键值对载荷 |
| Flags | 影响任务栈、权限授予等行为 |
| Package | 限制只匹配某包名(半显式) |
关系示意:
Intent
├─ component? → 有则显式,不再走 filter 匹配
├─ action / category
├─ data (uri) + type
├─ extras (Bundle)
└─ flags
设置 Data 与 Type 时注意:setData 会清 type,setType 会清 data;需同时设时用 setDataAndType。
5. Intent Filter 匹配规则
目标组件在 Manifest 声明 intent-filter 后,隐式 Intent 需同时满足:
5.1 Action
- Intent 的 action 必须与 Filter 中 某一个 action 相同
- Filter 无 action 则匹配不带 action 的 Intent(少见)
5.2 Category
- Intent 中的 每个 category 都必须在 Filter 中出现
startActivity会自动加CATEGORY_DEFAULT,故 Activity 的 filter 几乎必须写:
xml
<category android:name="android.intent.category.DEFAULT" />
5.3 Data
按 URI 的 scheme / host / port / path / pathPrefix / pathPattern 以及 mimeType 匹配。
多个 <data> 会组合成可匹配集合(具体以官方匹配算法为准)。
示例:
xml
<activity android:name=".WebActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Deep Link / App Links:BROWSABLE + https + Digital Asset Links 验证。
6. 常用 Action / Category / Data
6.1 常见 Action
| Action | 用途 |
|---|---|
ACTION_MAIN |
入口,配合 CATEGORY_LAUNCHER |
ACTION_VIEW |
查看数据(链接、地图、文件) |
ACTION_SEND / ACTION_SEND_MULTIPLE |
分享 |
ACTION_DIAL / ACTION_CALL |
拨号(CALL 需权限) |
ACTION_EDIT |
编辑 |
ACTION_PICK / ACTION_GET_CONTENT / ACTION_OPEN_DOCUMENT |
选择内容(推荐 SAF) |
ACTION_CREATE_DOCUMENT |
创建文档(SAF) |
ACTION_WEB_SEARCH |
网页搜索 |
ACTION_BATTERY_LOW 等 |
系统广播(多已限制静态注册) |
自定义 action 建议用包名反域:com.example.app.ACTION_SYNC。
6.2 常见 Category
| Category | 用途 |
|---|---|
CATEGORY_DEFAULT |
Activity 隐式启动必需 |
CATEGORY_LAUNCHER |
桌面图标入口 |
CATEGORY_BROWSABLE |
可被浏览器/链接唤起 |
6.3 Data 示例
kotlin
Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=Beijing"))
Intent(Intent.ACTION_DIAL, Uri.parse("tel:10086"))
Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "hello")
}
7. 传递数据
7.1 Extras
kotlin
intent.putExtra("key_string", "value")
intent.putExtra("key_int", 1)
intent.putExtra("key_parcelable", user) // Parcelable / 推荐 @Parcelize
val bundle = intent.extras
| 注意 | 说明 |
|---|---|
| 体积 | Intent 载荷有 Binder 事务大小限制(常见约 1MB 量级,宜远小于此) |
| 大图/大列表 | 用 Uri、磁盘缓存、ViewModel、单例仓库,勿塞巨型 Bitmap |
| 类型安全 | 可用类型安全封装或 Navigation Safe Args |
7.2 ClipData / URI 权限
分享文件时:
kotlin
val intent = Intent(Intent.ACTION_SEND).apply {
type = "application/pdf"
putExtra(Intent.EXTRA_STREAM, contentUri)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
clipData = ClipData.newUri(contentResolver, "pdf", contentUri)
}
使用 FileProvider 提供 content:// Uri,避免 file:// 与 FileUriExposedException。
8. 启动与结果回调
8.1 只启动
kotlin
startActivity(intent)
// 跨任务栈常见:
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
8.2 需要返回结果(现代写法)
kotlin
val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data
}
}
launcher.launch(Intent(this, EditActivity::class.java))
常用 Contract:TakePicture、GetContent、OpenDocument、RequestPermission 等。
目标页返回:
kotlin
setResult(RESULT_OK, Intent().putExtra("result", value))
finish()
旧 API startActivityForResult / onActivityResult 已不推荐。
9. Intent Flag
9.1 任务栈相关(Activity)
| Flag | 作用 |
|---|---|
FLAG_ACTIVITY_NEW_TASK |
在新任务中启动(非 Activity Context 常必需) |
FLAG_ACTIVITY_CLEAR_TOP |
若栈中已有目标,清除其上 Activity 并复用/重建 |
FLAG_ACTIVITY_SINGLE_TOP |
栈顶已是目标则不新建,走 onNewIntent |
FLAG_ACTIVITY_CLEAR_TASK |
常与 NEW_TASK 联用,清空目标任务再启动 |
FLAG_ACTIVITY_NO_HISTORY |
离开后不留在栈中 |
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
不进最近任务 |
与 launchMode(singleTop / singleTask 等)共同决定实例复用,需结合测试。
9.2 URI 权限相关
| Flag | 作用 |
|---|---|
FLAG_GRANT_READ_URI_PERMISSION |
授予接收方读 Uri |
FLAG_GRANT_WRITE_URI_PERMISSION |
授予写 |
FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
可持久化(需再 takePersistable) |
9.3 其他
| Flag | 作用 |
|---|---|
FLAG_ACTIVITY_NEW_DOCUMENT |
文档式多任务(近年多窗场景) |
| Receiver 相关 | 如 FLAG_RECEIVER_FOREGROUND 等(按场景查阅) |
10. PendingIntent
PendingIntent:交给其他应用/系统(通知、闹钟、桌面小部件)的「延迟触发 Intent 令牌」,由系统持有发送身份(按创建时的权限与身份)。
kotlin
val intent = Intent(context, TargetActivity::class.java)
val pending = PendingIntent.getActivity(
context,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
| 工厂方法 | 用途 |
|---|---|
getActivity |
拉起 Activity |
getBroadcast |
发广播 |
getService / getForegroundService |
启服务 |
可变性(Android 12+ 强制)
必须指定其一:
FLAG_IMMUTABLE:不可被填充修改(默认推荐)FLAG_MUTABLE:允许后续修改(如内联回复、需填充 Extra 的场景)
常与 FLAG_UPDATE_CURRENT / FLAG_CANCEL_CURRENT / FLAG_ONE_SHOT 组合。
| 优点 | 系统组件可代为拉起 App;权限模型清晰 |
| 缺点 | Flag 用错易安全漏洞或无法更新;后台启动 Activity 仍受限 |
11. 广播中的 Intent
kotlin
// 发送
sendBroadcast(Intent(ACTION_CUSTOM).setPackage(packageName)) // 显式包名更安全
// 动态注册(API 34+ 必须指定导出标志)
ContextCompat.registerReceiver(
context,
receiver,
IntentFilter(ACTION_CUSTOM),
ContextCompat.RECEIVER_NOT_EXPORTED
)
| 点 | 说明 |
|---|---|
| 显式广播 | 指定组件或 package,避免被第三方窃听 |
| 隐式 + 静态注册 | Android 8+ 大量禁止 |
| 有序广播 | sendOrderedBroadcast,可中止传播 |
| LocalBroadcastManager | 已废弃,改用应用内事件(Flow 等) |
12. 安全与高版本限制
| 版本/主题 | 影响 |
|---|---|
| Android 11 包可见性 | 查询/调起其他 App 需 <queries> 或可见性例外 |
| Android 12 exported | 含 intent-filter 的组件必须声明 android:exported |
| Android 12 PendingIntent | 必须 IMMUTABLE 或 MUTABLE |
| Android 12+ 隐式 Intent | 向非导出组件发送隐式 Intent 受限;匹配规则更严 |
| Android 10+ BAL | 后台启动 Activity 严格限制(通知 PendingIntent 等有例外路径) |
| Android 14 | 动态广播必须指定 exported;IntentSender/BAL 继续收紧 |
| File Uri | 禁止暴露 file:// 给其他 App,用 FileProvider |
原则:
- 应用内通信 → 显式 Intent
- 对外能力 → 最小化
exported=true+ 权限 - 分享文件 →
content://+ Grant Uri Permission - 调外部 App → 先
resolveActivity,并声明<queries>
xml
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<package android:name="com.other.app" />
</queries>
13. 常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
ActivityNotFoundException |
无匹配或包不可见 | resolveActivity;补 <queries> |
| 隐式启不起来 | 缺 CATEGORY_DEFAULT |
Filter 加上 DEFAULT |
setType 后 data 丢了 |
API 互斥 | 用 setDataAndType |
| TransactionTooLarge | Extras 过大 | 改传 Uri/ID |
| 通知点了没反应 | PendingIntent Flag/后台限制 | IMMUTABLE/UPDATE;符合 BAL 例外 |
| 分享图片对方打不开 | 未授权 Uri / 未设 ClipData | FLAG_GRANT_READ + ClipData |
| 非 Activity Context 崩溃 | 缺 NEW_TASK |
加 FLAG_ACTIVITY_NEW_TASK |
onNewIntent 没走 |
未 singleTop/Flag | 检查 launchMode 与 Flag |
14. 速查 Checklist
- 应用内跳转是否全部显式?
- Activity 隐式 filter 是否含
DEFAULT(及需要的BROWSABLE)? - 含 filter 的组件是否声明
exported? - 对外调起是否声明
<queries>? - Extras 是否够小?大对象是否改 Uri?
- 文件分享是否 FileProvider + Grant 权限?
- PendingIntent 是否含
IMMUTABLE/MUTABLE? - 结果回调是否已迁 Activity Result API?
- Service/广播是否符合后台与导出新规?
15. 优缺点与选型
Intent 机制整体
| 优点 | 系统级解耦;易调起系统能力;组件模型统一 |
| 缺点 | 隐式匹配与安全策略复杂;载荷大小受限;后台行为年年收紧 |
怎么选
| 场景 | 建议 |
|---|---|
| 同 App 页面跳转 | 显式 Intent / Navigation 组件 |
| 要返回结果 | Activity Result API |
| 打开链接/分享/选文件 | 隐式 Intent + 系统 Contract |
| 通知/小组件/闹钟 | PendingIntent(IMMUTABLE 优先) |
| 应用内事件总线 | 不要用隐式广播;用 Flow / 共享 ViewModel |
| 跨 App 结构化数据 | ContentProvider,而非塞巨型 Extra |
16. 参考链接
- Intents and Intent Filters
- Common Intents
- PendingIntent
- Activity Result API
- Package visibility
- Share files with FileProvider
一句话: Intent 描述「要做什么」;应用内用显式,跨应用用隐式 + Filter;数据走 Extras/Uri,系统代发用 PendingIntent;始终处理 exported、包可见性、Uri 权限与后台启动限制。