Android Intent知识总结

Android Intent 知识总结

整理日期:2026-07-30

覆盖:显式/隐式 Intent、Intent Filter、PendingIntent、Flag、安全限制与现代 API

官方:Intents and Intent Filters


目录

  • [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_DEFAULTLAUNCHER
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:TakePictureGetContentOpenDocumentRequestPermission 等。

目标页返回:

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 不进最近任务

launchModesingleTop / 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

原则:

  1. 应用内通信 → 显式 Intent
  2. 对外能力 → 最小化 exported=true + 权限
  3. 分享文件 → content:// + Grant Uri Permission
  4. 调外部 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. 参考链接


一句话: Intent 描述「要做什么」;应用内用显式,跨应用用隐式 + Filter;数据走 Extras/Uri,系统代发用 PendingIntent;始终处理 exported、包可见性、Uri 权限与后台启动限制。

相关推荐
码农coding5 小时前
android12 systemUI 之锁屏
android
圆山猫5 小时前
[Virtualization](三):RISC-V H-extension 与 Guest 执行模式
android·java·risc-v
爱笑鱼6 小时前
Binder(七):getCallingUid() 读到的是谁?clearCallingIdentity() 又清掉了什么?
android
2501_9159090611 小时前
iOS 应用反调试技详解术 检测调试器的原理与防护实践
android·ios·小程序·https·uni-app·iphone·webview
Lvan的前端笔记12 小时前
AndroidX 完全入门指南
android·androidx
帅次12 小时前
Android 应用高级面试:Window 近1年高频追问 18 题
android·面试·职场和发展
总捣什么乱113 小时前
MySQL MySQL是怎么保证主备一致的?
android·mysql·adb
zzm62813 小时前
精读 HinDroid:基于异构信息网络的安卓恶意软件检测
android
weixin_4407841114 小时前
Android基础知识汇总
android·java·android studio
sbjdhjd14 小时前
安全初级 | Upload 文件上传漏洞实操
android·经验分享·安全·网络安全·开源·php·apache