Skip to content

Android 四大组件详解 📱

一、Activity(活动)

1.1 基本概念

Activity 是 Android 应用中负责用户界面交互的组件,每个 Activity 代表一个单独的屏幕窗口。

1.2 生命周期详解

┌─────────────┐
│  onCreate() │  → 初始化界面、数据
└──────┬──────┘

┌─────────────┐
│  onStart()  │  → 可见但不可交互
└──────┬──────┘

┌─────────────┐
│ onResume()  │  → 完全可见且可交互(前台)
└──────┬──────┘

   [用户操作]

┌─────────────┐
│  onPause()  │  → 失去焦点但还可见(部分被遮挡)
└──────┬──────┘

┌─────────────┐
│  onStop()   │  → 不可见(完全被遮挡)
└──────┬──────┘

┌─────────────┐
│onDestroy()  │  → 被销毁
└─────────────┘

面试考点

Q1: Activity 生命周期的完整调用顺序?

A:

  • 首次启动: onCreate()onStart()onResume()
  • 暂时切换到后台: onPause()onStop()
  • 从后台回到前台: onRestart()onStart()onResume()
  • 销毁: onPause()onStop()onDestroy()

Q2: 四种启动模式(launchMode)的区别?

A:

模式描述典型场景
Standard默认模式,每次启动都创建新实例大多数普通 Activity
SingleTop栈顶复用,如果实例已在栈顶则调用 onNewIntent()启动页、搜索结果页
SingleTask栈内复用,整个栈只有一个实例,会清除上面的 Activity浏览器首页、应用启动页
SingleInstance独立栈,独占一个任务栈来电界面、闹钟提醒

Q3: Intent 的四种类型?

A:

  1. Explicit Intent(显式): 指定具体组件类名
  2. Implicit Intent(隐式): 通过 Action、Data、Category 匹配
  3. Intercept Intent(拦截): 通过 Intent Filter 拦截
  4. Pending Intent(待处理): 授权其他应用使用自己的 Intent

Q4: Intent 传递数据的方式及限制?

A:

  • putExtra(): 传递基本数据类型、String、Serializable、Parcelable
  • Bundle 限制: 约 1MB(不同设备可能不同)
  • 大量数据传递: 推荐使用 ViewModel、SharedPreferences、数据库

二、Service(服务)

2.1 基本概念

Service 是在后台执行长时间运行操作而不提供 UI 的组件。

2.2 启动方式对比

kotlin
// 方式 1: startService() - 启动型服务
startService(Intent(this, MyService::class.java))

// 方式 2: bindService() - 绑定型服务
bindService(Intent(this, MyService::class.java), connection, Context.BIND_AUTO_CREATE)

生命周期对比

启动方式生命周期调用者死亡典型场景
startService()onCreate()onStartCommand()onDestroy()继续运行音乐播放、下载任务
bindService()onCreate()onBind()onUnbind()onDestroy()服务停止数据交互、ContentProvider

2.3 面试考点

Q1: Service 和 Thread 的区别?

A:

  • Service 不是独立线程:运行在主线程,需要耗时操作必须开启子线程
  • 生命周期:Service 由系统管理,Thread 需要手动管理
  • 使用场景:Service 适合跨组件调用,Thread 适合内部逻辑

Q2: Foreground Service(前台服务)的作用?

A:

  • 通过通知栏显示,优先级更高
  • 不易被系统杀死
  • 必须调用 startForeground() 显示通知
  • 需要 FOREGROUND_SERVICE 权限

Q3: Service 保活方案?

A:

  1. 前台服务:显示通知栏
  2. 闹钟保活:AlarmManager 定时重启
  3. JobScheduler:系统调度任务
  4. 互相启动:多个 Service 互相唤醒
  5. 监听系统广播:BOOT_COMPLETED、ACTION_SHUTDOWN
  6. Root 权限:最高级别(不推荐)

三、BroadcastReceiver(广播接收器)

3.1 分类

静态注册 vs 动态注册

kotlin
// 动态注册
val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // 处理广播
    }
}
registerReceiver(receiver, IntentFilter("ACTION_CUSTOM"))

// 静态注册 (AndroidManifest.xml)
<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="ACTION_BOOT_COMPLETED" />
    </intent-filter>
</receiver>

有序广播 vs 无序广播

类型描述特点
无序广播所有接收者同时收到快速、不可拦截
有序广播按优先级依次传递可中止传播、可修改数据

3.2 面试考点

Q1: 静态注册和动态注册的区别?

A:

  • 静态注册: 应用未启动也能接收,AndroidManifest.xml 中注册
  • 动态注册: 需要手动 unregister,应用运行期间有效
  • Android 12+: 静态注册受限,大部分广播改为动态注册

Q2: 为什么推荐本地广播?

A:

  • 安全性: 不跨进程,更可靠
  • 性能: 避免进程间通信开销
  • 注意: LocalBroadcastManager 已废弃,推荐使用 EventBus、Flow 等

Q3: 系统广播有哪些?

A:

  • ACTION_BOOT_COMPLETED: 系统启动完成
  • ACTION_SHUTDOWN: 系统关机
  • ACTION_BATTERY_LOW: 电量低
  • ACTION_SCREEN_OFF: 屏幕关闭
  • CONNECTIVITY_ACTION: 网络连接变化(已废弃)

四、ContentProvider(内容提供者)

4.1 基本概念

ContentProvider 是 Android 提供的在应用之间共享数据的标准接口。

4.2 核心操作

kotlin
// CRUD 操作
ContentResolver.insert(uri, values)        // 插入
ContentResolver.query(uri, columns, ...)   // 查询
ContentResolver.update(uri, values, ...)   // 更新
ContentResolver.delete(uri, ...)           // 删除

4.3 面试考点

Q1: ContentProvider 的作用?

A:

  • 数据共享: 在不同应用之间安全地共享数据
  • 权限控制: 通过 permission 控制访问权限
  • 数据抽象: 提供统一的数据访问接口

Q2: UriMatcher 的作用?

A:

  • 解析 URI,匹配不同的数据路径
  • 返回匹配码,用于区分不同操作
kotlin
val matcher = UriMatcher(UriMatcher.NO_MATCH)
matcher.addURI("com.example.provider", "books", BOOKS)
matcher.addURI("com.example.provider", "books/#", BOOK_ID)

Q3: Cursor 的特点?

A:

  • 指向数据游标,类似数据库结果集
  • 需要手动 close() 避免内存泄漏
  • Android 推荐使用 LoaderRoom 自动管理

五、综合问题

Q1: Activity 和 Service 如何通信?

A:

  1. BroadcastReceiver: 通过广播通信
  2. Binder: bindService 绑定
  3. Messenger: 远程通信(基于 AIDL)
  4. LocalSocket: 本地 Socket 通信
  5. AIDL: 跨进程通信
  6. SharedPreference/数据库: 共享数据

Q2: 什么是 Intent?

A: Intent 是 Android 组件间通信的"消息包",包含:

  • Action: 动作描述(如 Intent.ACTION_VIEW)
  • Data: 数据 URI
  • Type: 数据 MIME 类型
  • Category: 分类信息
  • Component: 目标组件类名
  • Extras: 附加数据

Q3: 隐式 Intent 如何匹配?

A: 匹配顺序:

  1. Component: 指定组件,直接匹配
  2. Action: 匹配 IntentFilter 的 action
  3. Data: 匹配 data 和 mimeType
  4. Category: 所有 category 都要匹配
  5. Permission: 需要相应权限

Q4: PendingIntent 的作用?

A:

  • 授权其他应用使用自己的 Intent
  • 用于闹钟、通知、快捷方式等场景
  • 类型:startActivity、startService、sendBroadcast

六、实战代码示例

Activity 启动示例

kotlin
// 显式启动
val intent = Intent(this, TargetActivity::class.java)
intent.putExtra("key", "value")
startActivity(intent)

// 隐式启动
val intent = Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("https://example.com")
}
startActivity(intent)

// 启动并获取结果
startActivityForResult(intent, REQUEST_CODE)

// AndroidX 推荐方式
val launcher = registerForActivityResult(StartActivityResult()) { result ->
    // 处理结果
}
launcher.launch(intent)

Service 启动示例

kotlin
// 启动服务
startService(Intent(this, MyService::class.java))

// 绑定服务
bindService(Intent(this, MyService::class.java), connection, Context.BIND_AUTO_CREATE)

// 前台服务
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("Music Player")
        .setContentText("Playing...")
        .setSmallIcon(R.drawable.ic_music)
        .build()
    startForeground(1, notification)
    return START_STICKY // 服务被杀后自动重启
}

七、性能优化建议

  1. Activity 启动优化

    • 避免在 onCreate 中加载大量数据
    • 使用 launchMode 合理复用 Activity
    • 预加载下一个页面资源
  2. Service 优化

    • 及时 stopSelf()stopService()
    • 前台服务显示必要通知
    • 避免在 Service 中直接操作 UI
  3. Broadcast 优化

    • 优先使用动态注册
    • 避免注册过多广播
    • 使用 sticky 广播注意内存
  4. ContentProvider 优化

    • 使用 ContentObserver 监听变化
    • 合理分页加载数据
    • 避免在主线程操作数据库

八、常见面试题汇总

问题难度出现频率
Activity 生命周期⭐⭐⭐⭐⭐⭐⭐
四种启动模式⭐⭐⭐⭐⭐⭐⭐
Service vs Thread⭐⭐⭐⭐⭐⭐
广播注册区别⭐⭐⭐⭐⭐
ContentProvider 作用⭐⭐⭐⭐⭐
Intent 传递数据限制⭐⭐⭐⭐⭐⭐

📚 参考资料

🔗 下一篇: Activity 生命周期深度解析