现代 Android 开发

最后更新: 2026-02-10 13:57:26 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

现代 Android 应用通常使用 Kotlin、AndroidX、Jetpack 库和 Jetpack Compose。平台 API 仍位于 android.* 中;AndroidX 在 androidx.* 中提供兼容不同版本且更高层的 API。应用包拥有多个由系统管理的入口点,而不是传统的进程级 main() 方法。

应用隔离 #

Android 为已安装的包分配 Linux UID,并赋予其私有文件基于 UID 的所有权。应用进程运行自己的 Android Runtime 实例,跨包组件调用使用 Binder IPC。运行时权限、SELinux 和框架服务检查会补充 UID 边界。

共享 UID 曾经可供签名相同的包使用,但由于会削弱包隔离,已不再建议新应用使用。应用应通过明确的接口共享数据,例如受权限保护的内容提供程序、文档选择器、URI 授权或 Binder 服务,而不是通过私有路径。

组件和清单 #

Android 有四种组件类型:

  • Activity 承载聚焦的用户界面。
  • Service 执行没有 Activity UI 的工作。长时间运行且对用户可见的工作需要前台服务通知,并受平台限制。
  • Broadcast receiver 对广播执行短暂响应,并应将较长工作委托给适当的调度器。
  • Content provider 通过 ContentResolver API 暴露结构化数据。

清单声明应用组件、权限、必要时的包可见性、最低 SDK 级别、功能和应用元数据。带有 intent filter 的组件只有在其 android:exported 设置和适用权限允许时,才能被外部寻址。应将非公开组件保持为未导出。

Intent 和组件激活 #

显式 intent 标识特定组件。隐式 intent 描述操作、数据、类别和可选 extras;系统根据已导出的 intent filter 解析它。对于内部操作和服务,应使用显式 intent,因为隐式服务 intent 可能解析到非预期组件。

Activity 通过 startActivity 或 Activity Result API 启动。服务根据其执行模型使用 startService、startForegroundService 或 bindService。不需要立即执行的后台工作应属于 WorkManager,或在适当时属于 JobScheduler,而不是长期运行的后台服务。

将所有传入的 intent、extras 和 URI 视为不可信输入。在 API 允许时验证调用者,验证值,为敏感组件要求权限,并且仅在必要的范围和时间内授予 URI 权限。

Activity 生命周期和状态 #

系统通过 onCreate 创建 Activity,通过 onStart 使其可见,并通过 onResume 使其可交互。onPause 表示 Activity 已失去前台焦点;它必须快速返回。Activity 不再可见时会触发 onStop,这是释放仅在可见期间需要的资源的适当位置。

Activity 可能因为请求了 finish,或因为系统回收其进程而被销毁。对于后一种情况, onSaveInstanceState 保存少量可重建的 UI 状态。框架会保存受支持的视图层次状态,但应用状态应根据其大小和生命周期存放在 ViewModel、保存状态句柄、数据库或其他持久存储中。不要使用生命周期回调执行无界的网络事务或数据库迁移。

资源 #

Android 资源系统会将 res/ 条目编译为 R.string.app_name 等生成的标识符。将每种资源放在有类型的顶层目录中,例如 layout、drawable、mipmap、values、xml、font、menu、raw、anim 或 animator。放在 assets/ 中的资产不会编译到 R,而是通过 AssetManager 打开。

资源限定符会根据配置、区域设置、屏幕尺寸、密度、方向和夜间模式选择最合适的替代项。限定符必须使用文档规定的顺序,并且不能重复限定符类型。应用引用的每个资源都应保留默认资源,因为设备配置可能与专用替代项不匹配。

Kotlin、Jetpack 和 Compose #

Kotlin 提供空安全、扩展函数、lambda、密封类型和协程。AndroidX 和 Jetpack 提供生命周期感知组件、Navigation、Room、WorkManager 和兼容性 API。lifecycleScope 和 viewModelScope 将协程绑定到其所有者,但取消并不会消除使工作幂等或处理失败的需要。

Jetpack Compose 将 UI 表达为可组合函数。Activity 通过 setContent 进入 Compose;收集到组合中的可观察状态会使受影响的 UI 重新组合。LazyColumn 提供高效的基于项目的布局,修饰符表达布局、交互和装饰。

将屏幕状态保存在 ViewModel 中,使可组合函数主要成为状态的函数,并对生命周期取决于组合的工作使用 effect API。在分阶段迁移期间,Views 和 Compose 可以互操作,因此采用 Compose 不要求重写全部代码。

评论

在 GitHub 上阅读或评论(发表评论需要登录)