将 Kotlin 添加到现有应用

Android Studio 提供全面的 Kotlin 支持,让您能够将 Kotlin 文件添加到现有项目并将 Java 语言代码转换为 Kotlin 代码。然后,您可以使用 Android Studio 的所有现有工具来处理 Kotlin 代码,包括自动补全、lint 检查、重构和调试等。

如果您要开始一个新项目,并希望使用 Kotlin,请参阅创建项目

如需示例,请查看我们的 Kotlin 代码示例

将 Kotlin 添加到现有项目

如需将 Kotlin 添加到项目,请执行以下操作:

  1. 依次点击 File > New,然后从各种 Android 模板中选择一个,例如一个新的空白 Fragment,如图 1 所示。如果您未在此菜单中看到模板列表,请先打开 Project 窗口,然后选择您的应用模块。

    创建一个新的空白 fragment
    图 1.从可用模板中进行选择,例如 fragment 或 activity。
  2. 在随即显示的向导中,选择 Kotlin 作为 Source Language。图 2 显示了当您要创建新 activity 时使用的 New Android Activity 对话框。

    可让您选择 Kotlin 作为源语言的对话框
    图 2. New Android Activity 对话框,您可以从中选择 Kotlin 作为 Source Language
  3. 继续执行向导中的操作,直到完成。

或者,您也可以依次点击 File > New > Kotlin File/Class 以创建一个基本的 Kotlin 文件。如果您没有看到此选项,请打开 Project 窗口,然后选择 java 目录。在 New Kotlin File/Class 窗口中,您可以定义文件名并从多种文件类型中选择:FileClassInterfaceEnum ClassObject。您做出的选择决定了系统在新的 Kotlin 文件中为您创建的基本架构。如果您选择 Class,Android Studio 会创建一个具有给定名称和匹配类定义的新 Kotlin 源文件。如果您选择 Interface,系统会在文件中声明一个接口,诸如此类。

如果这是您首次直接将一个新的 Kotlin 类或文件添加到项目(不使用 Android 模板),Android Studio 会显示一条警告,指出项目中未配置 Kotlin,如图 3 所示。您可以在编辑器的右上角点击 Configure 或在右下角弹出的事件日志提醒中点击该按钮来配置 Kotlin。

提示您为项目配置 Kotlin 的警告对话框
图 3.如果没有为项目配置 Kotlin,Android Studio 会显示一个警告对话框。

出现提示时,选择用于为包含 Kotlin 文件的所有模块配置 Kotlin 的 All modules containing Kotlin files 选项,如图 4 所示:

选择为包含 Kotlin 代码的所有模块配置 Kotlin
图 4. 选择为包含 Kotlin 代码的所有模块配置 Kotlin。

您点击 OK 后,Android Studio 会将 Kotlin 添加到项目类路径,并将 Kotlin Android 插件应用于包含 Kotlin 文件的每个模块。build.gradle 文件应与以下示例类似:

Groovy

// Project build.gradle file.
buildscript {
    ext.kotlin_version = '1.4.10'
    ...
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

Kotlin

// Project build.gradle.kts file.
buildscript {
    extra["kotlin_version"] = "1.4.10"
    ...
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
    }
}

Groovy

// Inside each module using kotlin
plugins {
    ...
    id 'kotlin-android'
}

...

dependencies {
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

Kotlin

// Inside each module using kotlin
plugins {
    ...
    kotlin("android")
}

...

val kotlin_version: String by rootProject.extra

dependencies {
    implementation("androidx.core:core-ktx:1.3.2")
    implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
}

源代码组织

默认情况下,新的 Kotlin 文件保存在 src/main/java/ 中,这样方便您在一个位置同时查看 Kotlin 文件和 Java 文件。如果您希望将 Kotlin 文件与 Java 文件分开,可以将 Kotlin 文件放在 src/main/kotlin/ 下。如果这样做,则还需要在 sourceSets 配置中添加此目录,如下所示:

Groovy

android {
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }
}

Kotlin

android {
    sourceSets {
        getByName("main") {
            java.srcDir("src/main/kotlin")
        }
    }
}

将现有 Java 代码转换为 Kotlin 代码

如需将 Java 代码转换为 Kotlin 代码,请在 Android Studio 中打开 Java 文件,然后依次选择 Code > Convert Java File to Kotlin File。或者,也可以创建一个新的 Kotlin 文件(依次选择 File > New > Kotlin File/Class),然后将 Java 代码粘贴到该文件中。Android Studio 随即会显示一条提示,询问您是否要将代码转换为 Kotlin 代码,如图 5 所示。点击 Yes 即可转换。您可以选择性地勾选 Don't show this dialog next time,让系统将来自动进行转换。

选择为包含 Kotlin 代码的所有模块配置 Kotlin
图 5. Android Studio 可将 Java 代码转换为 Kotlin 代码。

代码转换和可为 null 性

Android Studio 的转换过程会生成在功能上等效且可正常编译和运行的 Kotlin 代码。不过,您可能需要对转换后的代码进行额外的优化。例如,您可能想要优化转换后的代码如何处理可为 null 类型。

在 Android 中,通常会延迟 View 对象及其他组件的初始化,直到它们附加到的 fragment 或 activity 达到适当的生命周期状态。例如,您可能在某个 fragment 中引用了一个按钮,如以下代码段所示:

public class JavaFragment extends Fragment {

    // Null until onCreateView.
    private Button button;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_content, container,false);

        // Get a reference to the button in the view, only after the root view is inflated.
        button = root.findViewById(R.id.button);

        return root;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // Not null at this point of time when onViewCreated runs
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ...
            }
        });
    }
}

尽管按钮变量可为 null,但实际上,在本例中使用时,它绝不能为 null。不过,由于在构建时没有为按钮变量赋值,因此生成的 Kotlin 代码将 Button 视为可为 null 类型,并在添加点击监听器时使用非 null 断言运算符来解封按钮,如下所示:

class JavaFragment : Fragment() {

    // Null until onCreateView.
    private var button: Button? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?): View? {
        ...
        // Get a reference to the button in the view, only after the root view is inflated.
        button = root.findViewById(R.id.button)
        ...
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Not null at the point of time when onViewCreated fires 
        // but force unwrapped nonetheless
        button!!.setOnClickListener { }
    }
}

对于这种情况,这种转换不如使用 lateinit 理想,因为您不得不在访问按钮引用的每个位置都使用非 null 断言或安全调用运算符来解封按钮引用。

在其他情况下(根据应用的用例,null 是有效的变量赋值),将安全调用运算符 (?.) 与终止 elvis 运算符 (?:) 结合使用可能是一种更合适的方法,可以安全地解封可为 null 对象或将其强制转换为合理的非 null 默认值。在转换过程中,Android Studio 没有足够的信息做出这一决定。虽然它默认为非 null 断言,但您应跟进并根据需要调整转换后的代码。

更多信息

如需详细了解如何在项目中同时使用 Kotlin 代码和 Java 代码,请参阅从 Kotlin 调用 Java 代码

如需详细了解如何在企业环境中使用 Kotlin,请参阅为大型团队采用 Kotlin

如需了解现有 Android API 的惯用 Kotlin 封装容器,请参阅 Android KTX