将 Kotlin 添加到现有应用

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

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

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

将 Kotlin 添加到现有项目

要将 Kotlin 添加到您的项目,请执行以下操作:

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

    create a new blank fragment
    图 1. 从可用模板中选择,例如 fragment 或 activity。
  2. 在出现的向导中,为 Source Language 选择 Kotlin。图 2 显示了创建新 activity 时显示的 New Android Activity 对话框。

    dialog that lets you choose Kotlin for your source language
    图 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。

warning dialog that prompts you to configure Kotlin for your
      project
图 3. 当您的项目未配置 Kotlin 时,Android Studio 会显示警告对话框。

出现提示时,选择为所有包含 Kotlin 文件的模块配置 Kotlin 的选项,如图 4 所示

choose to configure Kotlin for all modules that contain Kotlin code
图 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,这将使未来的转换自动进行。

choose to configure Kotlin for all modules that contain Kotlin code
图 5. Android Studio 可以将 Java 代码转换为 Kotlin。

代码转换和可空性

Android Studio 的转换过程会生成功能等效的 Kotlin 代码,该代码可以编译和运行。但是,您可能需要对转换后的代码进行额外的优化。例如,您可能希望优化转换后的代码处理可空类型的方式。

在 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。但是,由于其值在构造时未赋值,生成的 Kotlin 代码将 Button 视为可空类型,并在添加点击监听器时使用非空断言运算符来解包按钮,如下所示:

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 是有效的变量赋值,则使用安全调用 (?.) 运算符和终止 Elvis (?:) 运算符可能是更合适的方式来安全地解包可空对象或强制转换为合理的非空默认值。Android Studio 在转换过程中没有足够的信息来做出此判断。虽然它默认为非空断言,但您应根据需要后续调整转换后的代码。

更多信息

有关在项目中同时使用 Kotlin 和 Java 代码的更多信息,请参阅从 Kotlin 调用 Java 代码

有关在企业场景中使用 Kotlin 的更多信息,请参阅大型团队采用 Kotlin

有关现有 Android API 的惯用 Kotlin 封装器信息,请参阅Android KTX