Cicida

每日小C知识点

每天一个干货小贴士,记录学无止境的足迹

Kotlin 的 use 函数

在 Java 时代,处理资源(比如读写文件、数据库 Cursor)是一件很痛苦的事,因为最后必须要放在 finally 块里手动 close()。一旦忘记关“水龙头”,就会造成内存泄漏(水漫金山啦!)。

在 Kotlin 里,任何实现了 CloseableAutoCloseable 接口的对象(比如 File、Stream、Cursor、Socket),都可以直接调用 .use {}

FileReader("test.txt").use { reader ->
    // 在这个大括号里尽情读文件
    println(reader.readText())
} // ⬅️ 只要代码一离开这个大括号,它就会自动帮你执行 reader.close()!

为什么 use 这么厉害?

  1. 绝对安全:哪怕发生异常(Crash),它也会在崩溃前先帮你把资源关掉。
  2. 零性能损耗:它是一个 inline(内联)函数,在编译时会直接铺开,不会产生额外的函数调用开销。
  3. 保留真实异常:如果业务抛了异常,close 也抛了异常,它会聪明地把 close 异常压到业务异常下(Suppressed),不会吃掉真实报错。

一句话:需要 close() 的东西,别犹豫,套上 .use {} 就对了!✨

Version Catalog 的避坑法则

当我们在 Android 项目中使用 Version Catalog (libs.versions.toml) 来集中管理插件和依赖时,有一个非常容易踩的深坑!

⚠️ 核心避坑指南: 所有在子模块中实际 apply(应用)的插件,都必须先在项目根目录build.gradle.kts 中声明,并且显式地加上 apply false

// 根目录的 build.gradle.kts
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
}

🤔 为什么要多此一举?

这是由 Gradle 的运行机制决定的: 在项目构建前,Gradle 需要先解析所有插件的 classpath(也就是搞清楚去哪里下载这些插件的代码)。 如果在根项目中不预先声明并设为 apply false,直接在子模块调用,Gradle 就找不到下载路径。

根项目的这行代码,其实是在告诉 Gradle:“你负责帮我去把这些插件的包下载好,放在那里备用,但先不要在我这个根项目上执行任何操作(下载但不应用)。”

只有当根项目做好了这步准备工作,底下的子模块在声明插件时,才能顺利调用并让插件真正在自己身上生效!这可是现代 Android 工程化管理的基础常识哦!✨