Build các phiên bản apk với tính năng khác nhau bằng flavors trong Android Studio

Xin chào các bạn!

Trong project tôi đang làm khách hàng có yêu cầu chia làm 3 phiên bản development, staging, production mỗi phiên bản lại có sự khác nhau về tính năng, các urls api ... Sẽ có người nghĩ ra cách là phát triển trên 3 branch khác nhau nhưng bất tiện là mỗi khi viết thêm source code bạn sẽ phải sang cả 3 branch để rebase nhánh chính.

Cách mà tôi làm đó là dùng productFlavors để chia ra các build variants khác nhau như sau:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0.0"
    }
    
     productFlavors {
        
        def URL_END_POINT = "URL_END_POINT"
        def APP_LINKS_HOST_NAME = "hostName"
        
        development {
            applicationId "com.framgia.awesome.development"
            versionNameSuffix '-DEV'
            manifestPlaceholders = [(APP_LINKS_HOST_NAME): "dev.domain.com"]
            buildConfigField "String", URL_END_POINT, "\"https://api.dev.domain.com\""
        }
        
        staging {
             applicationId "com.framgia.awesome.staging"
             versionNameSuffix '-STG'
             manifestPlaceholders = [(APP_LINKS_HOST_NAME): "staging.domain.com"]
             buildConfigField "String", URL_END_POINT, "\"https://api.staging.domain.com\""
        }
        
        production {
              applicationId "com.framgia.awesome"
              manifestPlaceholders = [(APP_LINKS_HOST_NAME): "domain.com"]
              buildConfigField "String", URL_END_POINT, "\"https://api.domain.com\""
        }
 }

Application Id

Mỗi phiên bản build variant sẽ có app id khác nhau tương ứng

Manifest Place holders

Bạn cũng có thể đặt một hoặc nhiều biến manifest place holders ví dụ như app name, api key tương ứng mỗi phiên bản, lưu ý nếu có nhiều biến bạn cần đặt dạng map như ví dụ trên

API URLS

Tôi sử dụng buildConfigFields để cấu hình api urls như vậy tùy theo build variants chúng ta chọn lúc build mà app sẽ chạy trên url tương ứng. Khi sử dụng chỉ cần gọi BuildConfig.URL_END_POINT và không cần quan tâm đến build variant hiện tại là gì

Resources khác nhau

Ví dụ 3 phiên bản có 3 icon, app name khác nhau thì với flavors sẽ dễ dàng làm được điều đó như sau Trong thư mục src của dự án tạo các thư mục tương ứng có tên giống với các flavors, trong mỗi thư mục tạo thư mục con tên là res/drawableres/values Với mỗi phiên bản flavor bạn chỉ cần đặt file icon vào thư mục drawable (hoặc các thư mục mipmap-xhdpi ...) tương ứng. Tạo file strings.xml trong thư mục res/values và mỗi file string khai báo 1 app_name tùy theo phiên bản. Khi chọn variants để build gradle sẽ build ra apk với app icon, app name và các thông tin cấu hình bên trên tương ứng cho bạn.

Source code khác nhau

Ví dụ mình có 2 phiên bản ứng dụng, trả phí và miễn phí, phiên bản trả phí sẽ không có quảng cáo Lúc này để sử dụng flavors làm được điều đó trước hết mình phải có 1 class AdsManager nhưng mỗi flavor sẽ được implement khác nhau, với bản trả phí AdsManager sẽ ẩn quảng cáo đi và không load quảng cáo về nữa và ngược lại với bản miễn phí. Cách làm cũng tương tự như Resources đó là trong thư mục src tạo các thư mục tương ứng với flavors Tại các thư mục tương ứng với flavor bạn tạo thư mục `java/package_name/AdsManager.java

Khi muốn chạy với phiên bản nào bạn chỉ cần vào Build Variants để chọn, gradle sẽ build ra bản tương ứng cho bạn

Trên đây là một số ứng dụng flavors của mình trong dự án, nhờ flavors mà việc chia phiên bản dễ dàng hơn rất nhiều. Xin cảm ơn.