Thêm Kotlin vào một ứng dụng hiện có

Android Studio cung cấp dịch vụ hỗ trợ đầy đủ cho Kotlin, cho phép bạn thêm các tệp Kotlin vào dự án hiện có và chuyển đổi mã nguồn từ ngôn ngữ Java sang Kotlin. Sau đó, bạn có thể sử dụng tất cả công cụ hiện có của Android Studio bằng mã Kotlin, bao gồm cả tính năng tự động hoàn thành, kiểm tra để tìm lỗi mã nguồn, tái cấu trúc, gỡ lỗi, v.v.

Nếu bạn đang bắt đầu một dự án mới và muốn sử dụng Kotlin, hãy xem bài viết Tạo dự án.

Để xem ví dụ mẫu, hãy xem bài viết Mã mẫu bằng Kotlin của chúng tôi.

Thêm Kotlin vào một dự án hiện có

Để thêm Kotlin vào dự án của bạn, hãy làm như sau:

  1. Nhấp vào File (Tệp) > New (Mới) rồi chọn một trong các mẫu cho Android, chẳng hạn như một Fragment (Mảnh) trống mới như trong hình 1. Nếu bạn không thấy danh sách mẫu trong trình đơn này, trước tiên, hãy mở cửa sổ Project (Dự án) rồi chọn mô-đun ứng dụng của bạn.

    tạo một mảnh trống mới
    Hình 1. Chọn trong số các mẫu có sẵn, chẳng hạn như mảnh (fragment) hoặc hoạt động (activity).
  2. Trong trình hướng dẫn xuất hiện, hãy chọn Kotlin cho Source Language (Ngôn ngữ nguồn). Hình 2 cho thấy hộp thoại New Android Activity (Hoạt động mới trên Android) khi bạn muốn tạo hoạt động mới.

    hộp thoại cho phép bạn chọn Kotlin cho ngôn ngữ nguồn của mình
    Hình 2. Hộp thoại New Android Activity (Hoạt động Android mới) cho phép bạn chọn Kotlin làm Source Language (Ngôn ngữ nguồn).
  3. Tiếp tục thông qua trình hướng dẫn.

Ngoài ra, bạn có thể nhấp vào File > New > Kotlin File/Class (Tệp > Mới > Tệp/Lớp Kotlin) để tạo một tệp Kotlin cơ bản. Nếu bạn không thấy tuỳ chọn này, hãy mở cửa sổ Project (Dự án) rồi chọn thư mục java. Cửa sổ New Kotlin File/Class (Tệp/Lớp Kotlin) cho phép bạn xác định tên tệp và cung cấp một số lựa chọn cho loại tệp: File (Tệp), Class (Lớp), Interface (Giao diện), Enum Class (Lớp enum) hoặc Object (Đối tượng). Lựa chọn bạn đưa ra sẽ quyết định các yếu tố cơ bản được tạo trong tệp Kotlin mới. Nếu bạn chọn Class (Lớp), Android Studio sẽ tạo một tệp nguồn Kotlin mới có tên cho sẵn và một định nghĩa lớp phù hợp. Nếu bạn chọn Interface (Giao diện), thì một giao diện sẽ được khai báo trong tệp, v.v.

Nếu đây là lần đầu tiên bạn trực tiếp thêm lớp hoặc tệp Kotlin mới vào dự án của mình (không sử dụng mẫu cho Android), thì Android Studio sẽ hiện một cảnh báo cho biết Kotlin không được định cấu hình trong dự án, như minh hoạ trong hình 3. Định cấu hình Kotlin bằng cách nhấp vào Configure (Định cấu hình) ở góc trên bên phải của trình chỉnh sửa hoặc trong cảnh báo nhật ký sự kiện bật lên ở góc dưới bên phải.

hộp thoại cảnh báo nhắc bạn định cấu hình Kotlin cho dự án
Hình 3. Android Studio sẽ hiện hộp thoại cảnh báo khi bạn không định cấu hình Kotlin cho dự án.

Khi có lời nhắc, hãy chọn tuỳ chọn định cấu hình Kotlin cho All modules containing Kotlin files (Tất cả mô-đun chứa tệp Kotlin), như minh hoạ trong hình 4:

chọn cách định cấu hình Kotlin cho tất cả mô-đun có chứa mã Kotlin
Hình 4. Chọn cách định cấu hình Kotlin cho tất cả mô-đun có chứa mã Kotlin.

Sau khi bạn nhấp vào OK, Android Studio sẽ thêm Kotlin vào classpath của bạn và áp dụng trình bổ trợ Kotlin Android cho từng mô-đun có chứa tệp Kotlin. Các tệp build.gradle của bạn sẽ trông giống như ví dụ dưới đây:

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")
}

Sắp xếp mã nguồn

Theo mặc định, các tệp Kotlin mới được lưu vào src/main/java/, giúp bạn dễ dàng xem cả tệp Kotlin và tệp Java ở một vị trí. Nếu muốn tách các tệp Kotlin khỏi các tệp Java, thì bạn có thể đặt các tệp Kotlin trong src/main/kotlin/. Nếu làm như vậy, thì bạn cũng cần đưa thư mục này vào cấu hình sourceSets của mình, như minh hoạ dưới đây:

Groovy

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

Kotlin

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

Chuyển đổi mã Java hiện tại sang mã Kotlin

Để chuyển đổi mã Java sang Kotlin, hãy mở tệp Java trong Android Studio, rồi chọn Code (Mã) > Convert Java File to Kotlin File (Chuyển đổi tệp Java sang tệp Kotlin). Một cách khác là tạo một tệp Kotlin mới (File (Tệp) > New (Mới) > Kotlin File/Class (Tệp/Lớp Kotlin)), rồi dán mã Java vào tệp đó. Sau đó, Android Studio sẽ hiện lời nhắc và đề nghị chuyển mã của bạn sang Kotlin, như minh hoạ trong hình 5. Nhấp vào Yes (Có) để chuyển đổi. Bạn có thể tuỳ ý chọn Don't show this dialog next time (Lần sau không hiện hộp thoại này). Thao tác này sẽ giúp các lượt chuyển đổi sau này diễn ra tự động.

chọn cách định cấu hình Kotlin cho tất cả mô-đun có chứa mã Kotlin
Hình 5. Android Studio có thể chuyển đổi mã Java sang Kotlin.

Chuyển đổi mã và tính chất rỗng

Quá trình chuyển đổi của Android Studio sẽ tạo ra mã Kotlin có chức năng tương đương để biên dịch và chạy. Tuy nhiên, có thể bạn vẫn cần tối ưu hoá thêm cho mã đã chuyển đổi. Ví dụ: có thể bạn sẽ muốn điều chỉnh cách mã chuyển đổi xử lý các loại có thể nhận giá trị rỗng.

Thông thường, trong Android, bạn có thể trì hoãn việc khởi tạo đối tượng View và các thành phần khác cho đến khi mảnh hoặc hoạt động đi kèm đạt đến trạng thái vòng đời (lifecycle) thích hợp. Ví dụ: bạn có thể tham chiếu đến một nút trong một mảnh, như minh hoạ trong đoạn mã sau:

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) {
                ...
            }
        });
    }
}

Mặc dù biến nút có thể nhận giá trị rỗng, nhưng về cơ bản, biến này không được rỗng khi sử dụng trong ví dụ này. Tuy nhiên, vì giá trị của biến này không được chỉ định vào thời điểm xây dựng, nên mã Kotlin đã tạo sẽ xem Button là loại có thể nhận giá trị rỗng và sử dụng toán tử xác nhận khác rỗng để bỏ bao bọc nút khi thêm một trình nghe lượt nhấp, như minh hoạ dưới đây:

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 { }
    }
}

Cách chuyển đổi này không hiệu quả bằng việc sử dụng lateinit cho trường hợp này, vì bạn bắt buộc phải bỏ bao bọc cho tham chiếu nút bằng một toán tử xác nhận khác rỗng hoặc toán tử an toàn cho lệnh gọi ở mọi nơi mà tham chiếu này được truy cập.

Trong các tình huống khác, khi null là lệnh gán biến hợp lệ theo trường hợp sử dụng của ứng dụng, thì việc sử dụng toán tử an toàn cho lệnh gọi (?.) cùng toán tử kết thúc elvis (?:) có thể là cách thích hợp hơn để bỏ bao bọc đối tượng có thể rỗng một cách an toàn hoặc chuyển đổi thành một giá trị rỗng mặc định hợp lý. Android Studio không có đủ thông tin để đưa ra quyết định này trong quá trình chuyển đổi. Mặc dù Android Studio sẽ mặc định xác nhận khác rỗng, nhưng bạn nên theo dõi và điều chỉnh mã đã chuyển đổi khi cần.

Thông tin khác

Để biết thêm thông tin về cách sử dụng cả mã Kotlin và mã Java trong dự án của bạn, hãy xem bài viết Gọi mã Java qua Kotlin.

Để biết thêm thông tin về cách sử dụng Kotlin cho các tình huống trong doanh nghiệp, hãy xem bài viết Sử dụng Kotlin cho các nhóm lớn.

Để biết thông tin về trình bao bọc tương thích với Kotlin cho các API Android hiện có, hãy xem Android KTX.