Android面试题库
四大组件
Intent

Intent

概述

Intent(意图)是Android中用于组件间通信的重要机制,它不仅可以启动Activity、Service和BroadcastReceiver,还可以在不同组件之间传递数据。Intent是Android组件间交互的纽带,是实现应用程序功能模块化的重要工具。

基本概念

1. Intent类型

  1. 显式Intent

    • 明确指定目标组件
    • 通常用于应用内部通信
    • 通过组件类名指定
  2. 隐式Intent

    • 指定行为而非具体组件
    • 系统匹配合适的组件
    • 通过Intent Filter匹配

2. 主要组成部分

  1. Component Name

    • 目标组件的类名
    • 可选,显式Intent必需
  2. Action

    • 要执行的操作
    • 如VIEW、CALL等
  3. Data

    • 操作的数据
    • URI格式
  4. Category

    • 组件类别
    • 附加信息
  5. 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的工作原理?

  1. Intent匹配过程

    • 匹配Action
    • 匹配Category
    • 匹配Data
  2. 匹配规则

    • Action必须完全匹配
    • Category必须完全包含
    • Data的URI和Type匹配

2. 显式Intent和隐式Intent的区别?

  1. 显式Intent

    • 明确指定目标组件
    • 效率更高
    • 应用内部使用
  2. 隐式Intent

    • 描述要执行的操作
    • 系统匹配合适组件
    • 跨应用通信

3. Intent可以传递哪些数据?

  1. 基本数据类型

    intent.putExtra("int", 1)
    intent.putExtra("string", "text")
  2. Bundle

    val bundle = Bundle()
    bundle.putString("key", "value")
    intent.putExtras(bundle)
  3. Serializable对象

    intent.putExtra("object", serializableObject)
  4. Parcelable对象

    intent.putExtra("parcelable", parcelableObject)

4. PendingIntent的作用是什么?

  1. 延迟意图

    • 让其他应用代为执行
    • 可以撤销或更新
  2. 使用场景

    • 通知栏操作
    • 桌面小部件
    • 定时任务

5. Intent Flag的常见用法?

  1. 任务栈管理

    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_CLEAR_TOP
    • FLAG_ACTIVITY_SINGLE_TOP
  2. 启动模式控制

    • FLAG_ACTIVITY_NO_HISTORY
    • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

最佳实践

1. 安全性考虑

  1. 权限控制

    <activity android:exported="false" />
  2. 数据验证

    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }

2. 性能优化

  1. 避免大数据传输

    • 使用URI代替大文件
    • 考虑其他IPC方式
  2. 合理使用Flag

    • 避免不必要的任务栈
    • 正确管理Activity生命周期

3. 代码规范

  1. 常量定义

    companion object {
        const val EXTRA_KEY = "extra_key"
        const val ACTION_CUSTOM = "com.example.action.CUSTOM"
    }
  2. 类型安全

    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;
}

注意事项

  1. 内存泄漏

    • 避免传递大量数据
    • 及时释放资源
    • 使用WeakReference
  2. 兼容性

    • 处理不同Android版本
    • 考虑目标应用是否存在
    • 处理异常情况
  3. 安全性

    • 验证来源可靠性
    • 保护敏感数据
    • 使用显式Intent