Intent
概述
Intent(意图)是Android中用于组件间通信的重要机制,它不仅可以启动Activity、Service和BroadcastReceiver,还可以在不同组件之间传递数据。Intent是Android组件间交互的纽带,是实现应用程序功能模块化的重要工具。
基本概念
1. Intent类型
-
显式Intent
- 明确指定目标组件
- 通常用于应用内部通信
- 通过组件类名指定
-
隐式Intent
- 指定行为而非具体组件
- 系统匹配合适的组件
- 通过Intent Filter匹配
2. 主要组成部分
-
Component Name
- 目标组件的类名
- 可选,显式Intent必需
-
Action
- 要执行的操作
- 如VIEW、CALL等
-
Data
- 操作的数据
- URI格式
-
Category
- 组件类别
- 附加信息
-
Extras
- 附加数据
- 键值对形式
实现示例
1. 显式Intent
// 启动Activity
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra("key", "value")
}
startActivity(intent)
// 启动Service
val serviceIntent = Intent(this, MyService::class.java)
startService(serviceIntent)2. 隐式Intent
// 打开网页
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("https://www.example.com")
}
startActivity(intent)
// 拨打电话
val dialIntent = Intent(Intent.ACTION_DIAL).apply {
data = Uri.parse("tel:10086")
}
startActivity(dialIntent)3. Intent Filter
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>高级特性
1. PendingIntent
// 创建PendingIntent
val intent = Intent(this, NotificationActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
// 在通知中使用
val notification = NotificationCompat.Builder(this, channelId)
.setContentIntent(pendingIntent)
.build()2. Intent Flag
val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_CLEAR_TOP
}面试常见问题
1. Intent和IntentFilter的工作原理?
-
Intent匹配过程
- 匹配Action
- 匹配Category
- 匹配Data
-
匹配规则
- Action必须完全匹配
- Category必须完全包含
- Data的URI和Type匹配
2. 显式Intent和隐式Intent的区别?
-
显式Intent
- 明确指定目标组件
- 效率更高
- 应用内部使用
-
隐式Intent
- 描述要执行的操作
- 系统匹配合适组件
- 跨应用通信
3. Intent可以传递哪些数据?
-
基本数据类型
intent.putExtra("int", 1) intent.putExtra("string", "text") -
Bundle
val bundle = Bundle() bundle.putString("key", "value") intent.putExtras(bundle) -
Serializable对象
intent.putExtra("object", serializableObject) -
Parcelable对象
intent.putExtra("parcelable", parcelableObject)
4. PendingIntent的作用是什么?
-
延迟意图
- 让其他应用代为执行
- 可以撤销或更新
-
使用场景
- 通知栏操作
- 桌面小部件
- 定时任务
5. Intent Flag的常见用法?
-
任务栈管理
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_SINGLE_TOP
-
启动模式控制
- FLAG_ACTIVITY_NO_HISTORY
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
最佳实践
1. 安全性考虑
-
权限控制
<activity android:exported="false" /> -
数据验证
if (intent.resolveActivity(packageManager) != null) { startActivity(intent) }
2. 性能优化
-
避免大数据传输
- 使用URI代替大文件
- 考虑其他IPC方式
-
合理使用Flag
- 避免不必要的任务栈
- 正确管理Activity生命周期
3. 代码规范
-
常量定义
companion object { const val EXTRA_KEY = "extra_key" const val ACTION_CUSTOM = "com.example.action.CUSTOM" } -
类型安全
inline fun <reified T> Intent.getParcelableExtraCompat(key: String): T? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { getParcelableExtra(key, T::class.java) } else { @Suppress("DEPRECATION") getParcelableExtra(key) as? T } }
源码分析
1. Intent匹配过程
// PackageManagerService中的Intent匹配逻辑
public List<ResolveInfo> queryIntentActivities(Intent intent, String resolvedType,
int flags, int userId) {
// 1. 检查组件名
if (intent.getComponent() != null) {
// 显式Intent处理
}
// 2. 遍历所有IntentFilter
// 3. 进行匹配
}2. 数据传递机制
// Intent数据传递核心代码
public Intent putExtra(String name, Bundle value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putBundle(name, value);
return this;
}注意事项
-
内存泄漏
- 避免传递大量数据
- 及时释放资源
- 使用WeakReference
-
兼容性
- 处理不同Android版本
- 考虑目标应用是否存在
- 处理异常情况
-
安全性
- 验证来源可靠性
- 保护敏感数据
- 使用显式Intent