Android Intent 解析
一、Intent 核心知识体系(学习角度)
1. Intent 的本质与作用
本质:消息传递对象(Messaging Object)
核心功能:
组件激活(启动Activity/Service/Broadcast)
操作声明(ACTION_VIEW, ACTION_SEND等)
数据传递(键值对附加数据)
2. Intent 组成结构
public class Intent implements Parcelable, Cloneable {private String mAction; // 操作类型private Uri mData; // 数据URIprivate String mType; // MIME类型private String mPackage; // 目标包名private ComponentName mComponent; // 目标组件private int mFlags; // 启动标志private Bundle mExtras; // 附加数据
}
3. Intent 类型对比
特性 | 显式Intent | 隐式Intent |
---|---|---|
目标指定 | 明确指定组件名 | 通过Action/Category/Data匹配 |
使用场景 | 同应用内组件调用 | 跨应用组件调用 |
匹配机制 | 直接启动 | Intent Filter过滤匹配 |
安全性 | 高 | 需签名/权限验证 |
代码示例 | new Intent(this, Target.class) | new Intent(Intent.ACTION_VIEW) |
4. Intent Filter 匹配机制
Action匹配:Intent必须包含Filter声明的Action
Category匹配:Intent必须包含Filter所有Category
Data匹配:
URI方案(scheme)
主机名(host)
端口(port)
MIME类型
5. Intent 启动流程原理
二、常见问题
Q1:Intent 是什么?有什么作用?
A:
Intent是Android的消息传递对象,核心作用有三方面:
组件间通信:启动Activity/Service,发送Broadcast
操作描述:通过ACTION声明操作类型(如查看、发送)
数据传递:携带URI和键值对数据
例如启动网页浏览:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com")); startActivity(intent);
Q2:显式Intent和隐式Intent有什么区别?
A:
两者的核心区别在于目标组件的指定方式:
特点 显式Intent 隐式Intent 目标指定 直接指定ComponentName 通过Action/Data匹配 使用范围 主要应用内 跨应用场景 安全性 高(明确目标) 需Intent Filter验证 匹配过程 直接启动 系统筛选合适组件 使用建议:
同应用组件调用 → 显式Intent
调用系统功能(相机/浏览器)→ 隐式Intent
问题3:Intent Filter 如何工作?
回答:
Intent Filter是组件在Manifest中声明的匹配规则,包含三个核心元素:
Action:必须至少匹配一个声明的Action
Category:Intent必须包含所有声明的Category
Data:需匹配URI方案和MIME类型
匹配流程:
系统收集所有声明匹配Filter的组件
过滤不匹配Action的组件
筛选包含所有Category的组件
检查Data URI和MIME类型
返回最佳匹配(或让用户选择)
Q4:PendingIntent 是什么?使用场景?
A:
PendingIntent是系统代理执行的Intent,本质是token对象,主要特点:
跨进程能力:系统进程持有执行权限
执行时机灵活:可在应用退到后台后触发
典型场景:
通知栏操作(Notification点击)
定时任务(AlarmManager触发)
App Widget点击事件
安全注意:
Android 12+需使用FLAG_IMMUTABLE
防止篡改:PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
Q5:Intent 传递数据有什么限制?
A:
Intent传数据需注意三个关键限制:
大小限制:
Binder事务缓冲区1MB(Android 8.0前为512KB)
实际数据建议<100KB,否则抛
TransactionTooLargeException
类型限制:
支持基本类型、String、Parcelable、Serializable
避免传递大Bitmap(使用文件URI代替)
安全限制:
跨应用传递需显式设置
FLAG_GRANT_READ_URI_PERMISSION
敏感数据需加密
最佳实践:
大数据 → 文件存储+URI传递
复杂对象 → 实现Parcelable接口
进程间通信 → 使用AIDL/Binder
三、扩展问题
Q1:Android 12 对Intent安全做了哪些改进?
A:
组件导出限制:
未声明
android:exported
的组件默认不可导出防止意外暴露组件
PendingIntent不可变性:
强制使用
FLAG_IMMUTABLE
标志阻止恶意应用篡改Intent内容
URI权限细化:
需显式声明
android:grantUriPermissions
限制文件URI的随意共享
Q2:如何实现Deep Link深度链接?
A:
实现步骤:
Manifest声明Intent Filter:
<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="example.com"/> </intent-filter>
Activity中处理Intent:
Uri data = getIntent().getData(); if(data != null) {String path = data.getPath(); // 解析路径参数 }
验证链接:
adb shell am start -W -a android.intent.action.VIEW -d "https://example.com/profile"
Q3:Intent Flag有哪些常用标志?
A:
常用标志位:
FLAG_ACTIVITY_NEW_TASK:在新任务栈启动
FLAG_ACTIVITY_CLEAR_TOP:清除栈顶Activity
FLAG_ACTIVITY_SINGLE_TOP:栈顶复用(同launchMode="singleTop")
FLAG_GRANT_READ_URI_PERMISSION:授予URI读权限
组合使用示例:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
四、原理理解
1. Binder驱动级通信
Intent跨进程传递通过Binder实现
数据序列化使用Parcelable(非Serializable)
2. 启动性能优化
显式Intent:直接跳转(O(1)复杂度)
隐式Intent:匹配过程耗时(O(n)复杂度)
优化建议:
// 预查询匹配组件 List<ResolveInfo> infos = packageManager.queryIntentActivities(intent, 0);
五、总结
核心概念:消息传递、组件激活、跨应用通信
关键区别:显式Intent(精准)vs 隐式Intent(灵活)
安全实践:导出控制、URI权限、PendingIntent不可变性
性能要点:避免大数据传递、预查询匹配组件
最新特性:Android 12导出限制、深链接验证