前言

Android开发中经常需要使用Context作为上下文,之前喜欢在Application中onCreate()定义,使用Kotlin后,还有跟好的方式,因此,这里做一下记录。

Kotlin 全局 Context 获取by lazy

正文

延迟获取

通过by lazy 获取 Context

  • 延迟执行:变量在声明时不会立即执行初始化,而是等到代码中第一次真正访问该变量时,才执行大括号内的逻辑。

  • 结果缓存:初始化代码只会执行一次,获取到的 Context 会被缓存,后续访问直接返回缓存值。

  • 默认线程安全by lazy 默认采用 LazyThreadSafetyMode.SYNCHRONIZED 模式,确保多线程环境下首次访问时只安全地初始化一次。

单例管理
object AppContextManager {
    val globalContext: Context by lazy(LazyThreadSafetyMode.PUBLICATION) {
        requireNotNull(AppGlobals.getInitialApplication()?.applicationContext) {
            "Application Context is not initialized yet!"
        }
    }
}
// 使用:AppContextManager.globalContext
顶层属性
// 文件: AppExtensions.kt
val globalContext: Context by lazy(LazyThreadSafetyMode.PUBLICATION) {
    requireNotNull(AppGlobals.getInitialApplication()?.applicationContext) {
        "Application Context is not initialized yet!"
    }
}
// 使用:直接 import 后调用 globalContext

对比

之前都是通过Application.onCreate()获取context,这种比较老的,下面对比一下前后的区别

对比维度Application中获取使用 by lazy
执行时机App 启动,Application.onCreate() 被调用时立即执行App 启动时不执行,直到业务代码首次访问时才初始化。
冷启动性能在关键启动路径塞入初始化逻辑,可能拖慢启动速度实现延迟加载,将非核心初始化延后,优化冷启动性能
线程安全赋值给普通 var 全局变量时,需手动处理多线程可见性。内部已处理并发访问,保证只安全地初始化一次。
架构设计容易导致 Application 变成臃肿的“上帝类”。可放在独立工具类或顶层文件中,做到职责单一

注意事项

  1. 绝对禁止缓存Activity ContextApplicationContext 生命周期与 App 一致,全局持有是安全的。但如果误将 Activity Context 缓存为全局变量,会导致 Activity 无法被回收,引发严重的内存泄漏。

  2. 异常缓存机制:如果 AppGlobals.getInitialApplication() 在首次访问时抛出异常,该异常会被 lazy 缓存,后续每次访问都会重复抛出同一个异常。必须确保 AppGlobals 在首次访问前已正确初始化。

  3. 避免在 UI 场景滥用:凡是跟 UI 相关的操作(如启动 Activity、弹出 Dialog、Layout Inflate),都应该使用 Activity 作为 Context,不能使用全局的 ApplicationContext。

参考文章

  1. AI 优化

相关文章

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...