Tổng quan về bản dựng Gradle

Các ứng dụng Android thường được xây dựng bằng bản dựng Gradle hệ thống. Trước khi đi sâu vào chi tiết về cách định cấu hình bản dựng, chúng ta sẽ khám phá các khái niệm đằng sau bản dựng để bạn có thể thấy được toàn bộ hệ thống.

Công trình là gì?

Hệ thống xây dựng sẽ chuyển đổi mã nguồn thành một ứng dụng có thể thực thi. Bản dựng thường liên quan đến nhiều công cụ để phân tích, biên dịch, liên kết và đóng gói ứng dụng hoặc thư viện. Gradle sử dụng phương pháp dựa trên tác vụ để sắp xếp và chạy các lệnh này.

Tasks gói gọn các lệnh để chuyển dữ liệu đầu vào thành đầu ra. Trình bổ trợ xác định các nhiệm vụ và cấu hình của chúng. Đang áp dụng một trình bổ trợ cho bản dựng của bạn sẽ đăng ký các tác vụ của nó và kết nối chúng với nhau bằng đầu vào và đầu ra. Ví dụ: áp dụng Trình bổ trợ Android cho Gradle (AGP) vào tệp bản dựng của bạn sẽ đăng ký tất cả các tác vụ cần thiết để tạo APK hoặc Thư viện Android. Trình bổ trợ java-library cho phép bạn tạo một tệp jar từ nguồn Java . Các trình bổ trợ tương tự tồn tại cho Kotlin và các ngôn ngữ khác, nhưng các trình bổ trợ khác vẫn tồn tại nhằm mở rộng trình bổ trợ. Ví dụ: trình bổ trợ protobuf dùng để thêm hỗ trợ protobuf cho các trình bổ trợ hiện có như AGP hoặc java-library.

Gradle ưu tiên quy ước hơn cấu hình để các trình bổ trợ sẽ đi kèm với các giá trị mặc định có sẵn, nhưng bạn có thể định cấu hình thêm thông qua Ngôn ngữ dành riêng cho miền (DSL) mang tính khai báo. DSL được thiết kế để bạn có thể chỉ định cái gì cần xây dựng, thay vì cách xây dựng. Logic trong trình bổ trợ quản lý "cách thức". Cấu hình đó được chỉ định trên nhiều tệp bản dựng trong dự án (và dự án phụ) của bạn.

Dữ liệu đầu vào của công việc có thể là tệp và thư mục, cũng như các thông tin khác được mã hoá dưới dạng Loại Java (số nguyên, chuỗi hoặc lớp tuỳ chỉnh). Đầu ra chỉ có thể là thư mục hoặc tệp vì chúng phải được ghi trên đĩa. Kết nối đầu ra tác vụ với một đầu ra tác vụ khác đầu vào công việc, liên kết các công việc lại với nhau để một công việc phải chạy trước công việc khác.

Mặc dù Gradle có hỗ trợ việc viết các khai báo tác vụ và mã tuỳ ý trong bản dựng của bạn , điều này có thể khiến công cụ gặp khó khăn hơn trong việc hiểu bản dựng và để bạn duy trì. Ví dụ: bạn có thể viết các bài kiểm thử cho mã bên trong trình bổ trợ nhưng không có trong tệp bản dựng. Thay vào đó, bạn nên hạn chế logic bản dựng và tác vụ khai báo với trình bổ trợ (mà bạn hoặc người khác xác định) và khai báo cách bạn muốn sử dụng logic đó trong các tệp bản dựng.

Điều gì sẽ xảy ra khi một bản dựng Gradle chạy?

Các bản dựng Gradle chạy theo 3 giai đoạn. Mỗi giai đoạn trong số này thực thi các phần khác nhau mà bạn xác định trong các tệp bản dựng.

  • Khởi chạy xác định những dự án và dự án phụ được đưa vào bản dựng và thiết lập các đường dẫn lớp chứa các tệp bản dựng và được áp dụng trình bổ trợ. Giai đoạn này tập trung vào một tệp cài đặt để bạn khai báo dự án bản dựng và vị trí để tìm nạp trình bổ trợ và thư viện.
  • Cấu hình đăng ký các nhiệm vụ cho từng dự án và thực thi bản dựng để áp dụng thông số kỹ thuật của bản dựng của người dùng. Điều quan trọng là phải hiểu mã cấu hình của bạn sẽ không có quyền truy cập vào dữ liệu hoặc các tệp được tạo trong khi thực thi.
  • Thực thi thực hiện "toà nhà" thực tế của ứng dụng. Kết quả của cấu hình là một Đồ thị không chu trình có hướng (DAG) của các tác vụ, thể hiện tất cả các bước tạo bản dựng bắt buộc mà người dùng yêu cầu ( tác vụ được cung cấp trên dòng lệnh hoặc dưới dạng mặc định trong tệp bản dựng). Chiến dịch này biểu đồ thể hiện mối quan hệ giữa các công việc, được thể hiện rõ ràng trong dựa trên dữ liệu đầu vào và đầu ra của nó. Nếu một công việc có dữ liệu đầu vào là kết quả của một tác vụ khác, thì tác vụ này phải chạy sau tác vụ khác. Chiến dịch này giai đoạn chạy các công việc không cập nhật theo thứ tự được xác định trong biểu đồ; nếu một tác vụ đầu vào không thay đổi kể từ lần thực thi gần đây nhất, Gradle sẽ bỏ qua bước này.

Để biết thêm thông tin, hãy xem phần Vòng đời bản dựng của Gradle.

DSL cấu hình

Gradle sử dụng một Ngôn ngữ dành riêng cho miền (DSL) để định cấu hình bản dựng. Phương pháp khai báo này tập trung vào việc xác định dữ liệu của bạn thay vì viết hướng dẫn từng bước (bắt buộc).

DSL cố gắng giúp mọi người, chuyên gia miền và lập trình viên dễ dàng đóng góp cho dự án, xác định ngôn ngữ nhỏ đại diện cho dữ liệu tự nhiên hơn. Các trình bổ trợ Gradle có thể mở rộng DSL để định cấu hình dữ liệu mà chúng nhu cầu cho nhiệm vụ của họ.

Ví dụ: định cấu hình phần Android của bản dựng có thể có dạng như sau:

Kotlin

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

Groovy

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

Mã DSL tương tự như sau:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

Mỗi khối trong DSL được biểu thị bằng một hàm nhận lambda định cấu hình thuộc tính đó và thuộc tính có cùng tên để truy cập vào thuộc tính đó. Điều này khiến trong tệp bản dựng của bạn giống như một thông số kỹ thuật dữ liệu.

Phần phụ thuộc bên ngoài

Hệ thống xây dựng Maven đã giới thiệu một thông số kỹ thuật phần phụ thuộc, lưu trữ và quản lý. Thư viện được lưu trữ trong kho lưu trữ (máy chủ hoặc thư mục), với siêu dữ liệu bao gồm phiên bản và phần phụ thuộc của chúng trên các thư viện khác. Bạn chỉ định kho lưu trữ để tìm kiếm, phiên bản của phần phụ thuộc mà bạn muốn sử dụng và hệ thống xây dựng sẽ tải chúng xuống trong quá trình tạo.

Cấu phần phần mềm Maven được xác định theo tên nhóm (công ty, nhà phát triển, v.v.), cấu phần phần mềm tên (tên thư viện) và phiên bản của cấu phần phần mềm đó. Thông thường, được biểu thị dưới dạng group:artifact:version.

Phương pháp này giúp cải thiện đáng kể hoạt động quản lý bản dựng. Bạn thường sẽ nghe thấy những câu như vậy được gọi là "kho lưu trữ Maven", nhưng đó là cách cấu phần phần mềm được đóng gói và xuất bản. Các kho lưu trữ và siêu dữ liệu này đã được được sử dụng lại trong một số hệ thống xây dựng, bao gồm cả Gradle (và Gradle có thể xuất bản lên các kho lưu trữ này). Kho lưu trữ công khai cho phép chia sẻ để mọi người cùng sử dụng, và kho lưu trữ của công ty lưu giữ các phần phụ thuộc nội bộ nội bộ.

Bạn cũng có thể mô-đun hoá dự án của mình thành các dự án phụ (còn gọi là "modules" (mô-đun) trong Android Studio), có thể được dùng làm phần phụ thuộc. Mỗi dự án phụ sẽ tạo ra kết quả (chẳng hạn như các lọ) có thể mà các dự án con hoặc dự án cấp cao nhất của bạn tiêu thụ. Cách này có thể giúp cải thiện thời gian xây dựng bằng cách tách riêng phần nào cần xây dựng lại, cũng như tách trách nhiệm của bạn trong ứng dụng.

Chúng ta sẽ tìm hiểu chi tiết hơn về cách chỉ định các phần phụ thuộc trong bài viết Thêm bản dựng phần phụ thuộc.

Biến thể bản dựng

Khi tạo một ứng dụng Android, bạn thường muốn tạo nhiều biến thể. Các biến thể chứa mã khác hoặc được tạo bằng các biến thể khác nhau bao gồm các loại bản dựng và phiên bản sản phẩm.

Loại bản dựng khác nhau về tuỳ chọn bản dựng đã khai báo. Theo mặc định, AGP sẽ thiết lập "bản phát hành" và "debug" nhưng bạn có thể điều chỉnh chúng và thêm các loại bản dựng khác (có thể cho thử nghiệm hoặc kiểm thử nội bộ).

Bản gỡ lỗi không giảm kích thước hoặc làm rối mã nguồn của ứng dụng, tăng tốc tạo và giữ nguyên tất cả biểu tượng. Thao tác này cũng đánh dấu ứng dụng là "có thể gỡ lỗi", ký bằng một khoá gỡ lỗi chung và cho phép truy cập vào các tệp ứng dụng đã cài đặt trên thiết bị. Nhờ vậy, bạn có thể khám phá trong các tệp và cơ sở dữ liệu trong khi chạy ứng dụng.

Bản phát hành sẽ tối ưu hoá ứng dụng, ký ứng dụng bằng khoá phát hành của bạn, và bảo vệ các tệp ứng dụng đã cài đặt.

Khi sử dụng phiên bản sản phẩm, bạn có thể thay đổi nguồn và phần phụ thuộc đi kèm các biến thể của ứng dụng. Ví dụ: bạn có thể muốn tạo "bản minh hoạ" và "đầy đủ" cho ứng dụng của mình, hoặc có thể là "miễn phí" và "có tính phí" thú vị. Bạn viết nguồn chung trong một "chính" thư mục source set và ghi đè hoặc thêm nguồn trong nhóm tài nguyên được đặt tên theo hương vị.

AGP tạo ra các biến thể cho từng tổ hợp loại bản dựng và phiên bản sản phẩm. Nếu bạn không xác định phiên bản, các biến thể sẽ được đặt tên theo loại bản dựng. Nếu bạn hãy định nghĩa cả hai, biến thể sẽ được đặt tên là <flavor><Buildtype>. Ví dụ: với bản dựng loại releasedebug cũng như các phiên bản demofull, AGP sẽ tạo biến thể:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

Các bước tiếp theo

Giờ bạn đã biết các khái niệm về bản dựng, hãy xem bản dựng Android cấu trúc trong dự án của mình.