Hướng dẫn cơ bản về Gradle trong dự án Android

Sau khi Android ra IDE chính thức Android Studio, chúng ta đã bắt đầu để ý tới các file cấu hình .gradle để phục vụ cho việc builds và cấu hình cho project Android. Trong bài viết giới thiệu cơ bản về cách cấu hình file gradle để buid ứng dụng Android cùng 1 số tiện ích của chúng.

1. Sử dụng Gradle làm trình building trong các ứng dụng Android

Quá trình build một dự án Android được xử ký bởi hệ thống build của Gradle. Nếu bạn tạo một dự án trong Android Studio, các mã Gradle sẽ được tự động tạo ra. Android studio bao bọc quá trình Gradle chạy.

Hệ thống build của Gradle được thiết kế để hỗ trợ các tình huống phức tạp trong việc tạo ra các ứng dụng Android

  • Multi-distribution (Đa phiên bản) Cùng một ứng dụng phải được tuỳ biến để phụ vụ các khách hàng và các công ty khác nhau.
  • Multi-Apk: Hỗ trọng tạo ra nhiều file apk với nhiều loại thiết bị khác nhau mà có thể tái sử dụng lại code hiện tại.

Android Studio bao bọc quá trình buils của Gradle. Nếu bạn nhấn nút Run trong Android Studio, các hành động Gradle tương ứng sẽ giúp bạn chạy ứng dụng.

2. Build ứng dụng sử dụng Gradle qua các dòng lệnh

Để build ứng dụng Android sử dụng Gradle qua dòng lệnh, bạn mở ternimal trực tiêp từ thư mục dự án. Điều này yêu cầu Gradle là đã được cài đặt trên máy tính. Hoặc bạn có thể sử dụng các wrapper Gradle (gradlew) để thực hiện build, lệnh này sẽ tải Gradle nếu cần thiết.

# build project, runs both the assemble and check task
gradle build

# build project complete from scratch
gradle clean build

# speedup second grandle build by holding it in memory
gradle build --daemon

Các dòng lệnh phía trên tạo ra thư mục build trong dự án. Mặc định, Gradle tạo ra 2 file .apk trong thư mục build/outputs/apk

Để build và chạy Unit tests trong JVM sử dụng dòng lệnh sau:

gradle test

Để build và chạy test trên device Android sử dụng lệnh sau:

gradle connectedCheck

3. Loại bỏ các tài nguyên và các lớp Java không sử dụng

Hệ thống build của Gradle cho Android hỗ trợ thu hẹp tài nguyên (resource shrinking) tại thời điểm build. Nó sẽ tự động loại bỏ các tài nguyên mà không sử dụng từ ứng dụng được đóng gói. Ngoài ra để loại bỏ các tài nguyên trong dự án mà ko cần thiết thiết cho việc chạy trực tiếp (run time), điều này cũng loại bỏ các tài nguyên không cần thiết từ các thư viện (library) bạn đang phụ thuộc. Điều này có thể làm giảm đáng kể kích thước cho ứng dụng của bạn.

Để cấpcấp phép hoạt động cho việc thu hẹp tài nguyên, bạn phải cập nhật lại file build gradle (build.gradle) như dưới đây:

android {
    ...

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

4. Build ra các phiên bản ứng dụng khác nhau

4.1 Build types

Android sử dụng mặc định 2 kiểu build: debugrelease và bạn có thể thay đổi thành nhiều cấu hình khác nhau trong tập tin build.gradle.

Hệ thống Gradle cũng có khả năng quản lý các biến thể (variants) khác nhau trong việc xây dựng ứng dụng. Trong 1 số trường hợp bạn uốn chia các ứng dụng thành các phiê bản khác nhau và sử dụng gradle là cách tuyệt vời để làm điều này.

Ví dụ, bạn có thể xác định xây dựng các biến thể khác nhau cho các loại thiết bị nào đó, giống như điện thoại hoặc máy tính bảng. Một trường hợp khác sử dụng Gradle cho phiên bản miễn phí và phiên bản trả phí.

4.2 Định nghĩa các phiên bản khác nhau cho sản phẩm

Trong thẻ đóng productFlavors của file app/build.gradle, bạn có thể thêm các biến thể khác nhau cho sản phẩm của bạn.

productFlavors {
    // Định nghĩa ra 2 sản phẩm 1 free và có phí.
    paid {
        // Khi build ứng dụng sẽ đổi tên package và version Name của ứng dụng
        applicationId = "com.your.package.paid"
        versionName = "ver1.0-paid"
    }

    free {
        applicationId = "com.vogella.android.gradlebuildflavors.free"
        versionName = "ver1.0-free"
    }

    ...
}

Toàn bộ file build.gradle có thể như dưới:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        // Các cài đặt mặc định
        applicationId "com.exam.gradleexamples"
        minSdkVersion 19
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        paid {
            applicationId = "com.vogella.android.gradlebuildflavors.paid"
            versionName = "1.0-paid"
        }

        free {
            applicationId = "com.vogella.android.gradlebuildflavors.free"
            versionName = "1.0-free"
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
    testCompile 'junit:junit:4.+'
}

Sau khi định nghĩa cấu hình như trên bản chọn vào cửa sổ Build Variants trong Android Studio sẽ nhìn thấy như ảnh sau đây:

gradle1.png

5. Một số các cấu hình hữu ích cho việc build ứng dụng

Sau đây là 1 số kinh nghiệm cấu hình Gradle rất tiện cho việc build ứng dụng Android. Từ việc thay đổi tên ứng dụng với nhiều version, package và thậm chí là thay đổi logic code trong Java để thay đổi Link server cho phù hợp với mục đích test ứng dụng của bạn.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion '23.0.2'

   // Các cài đặt mặc định
    defaultConfig {
        applicationId "com.yourpackage.vn"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }

    productFlavors {
    }

    lintOptions {
        abortOnError false
    }

    buildTypes {
        // Định nghĩa các biến như là 1 hằng số để tái sử dụng trong các kiểu build khác nhau
        // Nó sẽ tạo ra các biến giá trị mà bạn có thể gọi nó thông qua lớp BuildConfig.java
        // Lớp này được Gradle tự động tạo ra
        def BOOLEAN = "boolean"
        def STRING = "String"
        def TRUE = "true"
        def FALSE = "false"
        def DEV_MODE = "DEV_MODE"
        def SERVER_ENDPOINT = "SERVER_ENDPOINT";
        // TODO: Fake server
        def ENDPOINT_PROD = "\"http://localhost\""
        def ENDPOINT_STG = "\"http://192.168.1.1:3000\""

        // Định nghĩa mặc định cho chế độ debug (Bạn có thể đặt bất kì tên gì)
        debug {
            applicationIdSuffix ".dev"
            versionNameSuffix "-dev"
            buildConfigField(BOOLEAN, DEV_MODE, TRUE)
            buildConfigField(STRING, SERVER_ENDPOINT, ENDPOINT_STG)
            minifyEnabled false
        }

        // Định nghĩa một kiểu build khác được kế thừa từ các thuộc tính của kiểu debug
        // Và ghi đè thuộc tính hoặc thêm một thuộc tính bất kì.
        debug_dummy.initWith(buildTypes.debug)
        debug_dummy {
            buildConfigField(STRING, SERVER_ENDPOINT, "\"http://google.com.abc/\"")
        }

        // MỘt định nghĩa kiểu khác cũng ghi đè từ debug. Bạn có thể tư duuy logic để cài đặt phần này theo ý mình mong muốn
        debug_haibse.initWith(buildTypes.debug)
        debug_haibse {
            buildConfigField(STRING, SERVER_ENDPOINT, "\"http://192.168.1.123:3000/\"")
        }

Tham khảo