Multiple APK support trong Android.

Xin chào tất cả các bạn, hôm nay chúng ta sẽ cùng nhau tìm hiểu về Multiple APK support trong Android.

1. Multiple APK support trong Android là gì?

Multiple APK support trong Android là một tính năng cho phép nhà phát triển tải lên nhiều phiên bản apk khác nhau.Mỗi APK là một phiên bản hoàn chỉnh và độc lập cho ứng dụng của bạn, nhưng chúng chia sẻ cùng một danh sách ứng dụng trên Google Play và phải chia sẻ cùng tên gói và được ký với cùng một khóa phát hành (keystore). Tính năng này hữu ích cho các trường hợp ứng dụng của bạn không thể tiếp cận tất cả các thiết bị mong muốn chỉ với một APK. Khi nhắc đến việc này hẳn mọi người sẽ nghĩ đến Android App Bundle khi upload ứng dụng lên Google Play, với nó Google Play sẽ tự động tạo ra và cung cấp các bản apk tối ưu cho từng cấu hình thiết bị người dùng, điều đó giúp cho việc tải và cập nhật rất nhẹ nhàng với người dùng và cả nhà phát , rất ưu việt, tuy nhiên hôm nay chúng ta sẽ không tìm hiểu về nó mà là Multiple APK support.

2. Tại sao lại cần xuất bản nhiều phiên bản apk.

Có rất nhiều lý do cho việc này nhưng tự chung lại là khi bạn phát hành một ứng dụng, việc ứng dụng có thành công hay không phụ thuộc rất nhiều vào việc ứng dụng của bạn cung cấp trải nghiệm tốt cho càng nhiều thiết bị càng tốt, dĩ nhiên bạn có thể làm điều này trong một file apk, chúng ta thường xuyên phải làm điều đó, tuy nhiên khi việc này trở nên quá phức tạp bởi các tài nguyên thay thế làm cho apk phình to hoặc các khó khăn về mặt kỹ thuật ngăn cản do Android thì có quá là nhiều thiết bị với quá nhiều nhà phát triển tham gia tuỳ biến đủ thứ và việc này thì vượt quá khả năng của một file apk, khi đó bạn sẽ phải xây dựng nhiều file apk và Google Play sẽ giúp bạn phân phối tới các thiết bị phù hợp thông qua cấu hình hỗ trợ mà các bạn khai báo trong từng file apk. Việc này có thể đem lại cho bạn các lợi ích cụ thể như sau - và cũng là thứ mà hiện tại Google Play có thể hỗ trợ:

  • Hỗ trợ các định dạng cấu trúc OpenGL khác nhau với mỗi APK.
  • Hỗ trợ các kích thước màn hình và mật độ khác nhau với mỗi APK.
  • Hỗ trợ các tính năng thiết bị khác nhau với mỗi APK.
  • Hỗ trợ các phiên bản nền tảng khác nhau với mỗi APK.
  • Hỗ trợ các kiến trúc CPU khác nhau với mỗi APK (chẳng hạn như ARM hoặc x86, khi ứng dụng của bạn sử dụng NDK của Android).
  • Tối ưu hóa cho các thiết bị đặc biệt, chẳng hạn như những thiết bị chạy Android Go.

3. Cách thức hoạt động.

Với sự hỗ trợ tuyệt vời trên thì hẳn là chúng ta sẽ thắc mắc là Google Play sẽ làm việc đó như thế nào, việc này sẽ được thực hiện thông qua việc các bạn khai báo các thẻ trong từng file apk của mình như:

  • Hỗ trợ các định dạng cấu trúc OpenGL khác nhau -> Được khai báo dựa vào thẻ <supports-gl-texture> trong file Manifest với cấu trúc:
<supports-gl-texture
  android:name="string" />

với thuộc tính name là nơi các bạn định nghĩa các giá trị để xác định các phiên bản apk ví dụ như:

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> Hỗ trợ các thiết bị hỗ trợ OpenGl ES 2.0
<supports-gl-texture android:name="GL_AMD_compressed_3DC_texture" /> Hỗ trợ các thiết bị Nén kết cấu ATI 3Dc.
  • Hỗ trợ các kích thước màn hình và mật độ khác nhau -> Được khai báo dựa vào một trong các thẻ <supports-screens> hoặc <compatible-screens> trong file manifest, bạn không được dùng hai thẻ này cùng lúc và Google có khuyến nghị là các bạn chỉ nên sử dụng thẻ <supports-screens> mà thôi. Ví dụ này xảy ra khi bạn xuất bản một file apk dành riêng cho các thiết bị màn hình nhỏ và một bản khác dành riêng cho thiết bị màn hình lớn hơn. Với mặc định các giá trị trong <supports-screens> sẽ luôn là true nếu các bạn không định nghĩa lại ví dụ như:
<supports-screens android:resizeable=["true"| "false"]
                  android:smallScreens=["true" | "false"]
                  android:normalScreens=["true" | "false"]
                  android:largeScreens=["true" | "false"]
                  android:xlargeScreens=["true" | "false"]
                  android:anyDensity=["true" | "false"]
                  android:requiresSmallestWidthDp="integer"
                  android:compatibleWidthLimitDp="integer"
                  android:largestWidthLimitDp="integer"/>

hoặc là thẻ.

<compatible-screens>
    <screen android:screenSize=["small" | "normal" | "large" | "xlarge"]
            android:screenDensity=["ldpi" | "mdpi" | "hdpi" | "xhdpi"
                                   | "280" | "360" | "420" | "480" | "560" ] />
    ...
</compatible-screens>

Dĩ nhiên là với mỗi thuộc tính các bạn sẽ chọn true hoặc false theo ý muốn của các bạn. Tuy nhiên với trường hợp các kích cỡ màn hình thì Google khuyến nghị các bạn không nên chia apk ra chỉ vì điều đó và Google cũng hỗ trợ multi screen rất đầy đủ rồi và các bạn nên làm theo. Còn tại sao không nên dùng hai thẻ trên cùng nhau thì vì khi dùng cả hai sẽ dễ gây lỗi khi hai thành phần này conflict với nhau do sai sót khi khai bảo chẳng hạn.

  • Hỗ trợ các tính năng thiết bị khác nhau -> Được khai báo dựa vào thẻ <uses-feature> trong file Manifest với cấu trúc:
<uses-feature
  android:name="string"
  android:required=["true" | "false"]
  android:glEsVersion="integer" />

Ví dụ cụ thể như là với các thiết bị bắt buộc có camera và bluetooth chẳng hạn:

<uses-feature android:name="android.hardware.bluetooth" />
<uses-feature android:name="android.hardware.camera" />

Bằng cách chỉ định các tính năng mà ứng dụng của bạn yêu cầu, bạn cho phép Google Play chỉ hiển thị ứng dụng của mình cho người dùng có thiết bị đáp ứng các yêu cầu tính năng của ứng dụng, thay vì hiển thị cho tất cả người dùng.

  • Tối ưu hóa cho các thiết bị đặc biệt, chẳng hạn như những thiết bị chạy Android Go -> Phần này thì đơn giản hơn. Để nhắm mục tiêu đến các thiết bị chạy Android (phiên bản Go), APK của bạn cần khai báo <used-Feature android: name = "android.hardware.ram.low" android: required = "true"> trong file manifest. Và target api phải từ 26 trở lên và version code cũng phải để cao hơn so với phiên bản apk cho các thiết bị khác.
  • Giới hạn theo level api -> Phần này thì khá là quen thuộc. Các bạn có thể làm điều này dựa vào thẻ <used-sdk> file manifest của bạn. Bạn có thể sử dụng cả hai thuộc tính android: minSdkVersionandroid: maxSdkVersion để chỉ định hỗ trợ cho các cấp API khác nhau.
  • Giới hạn theo kiến trúc của cpu( chẳng hạn chip của intel thì khác với qualcom chẳng hạn) -> Các bạn có thể thực hiện việc này thông qua việc khai báo trong file build.gradle của ứng dụng của bạn, ví dụ như:
buildTypes {
        getByName(BuildType.debug) {
            isDebuggable = true
            isMinifyEnabled = false
            ndk {
                setAbiFilters(listOf("armeabi-v7a"))
            }
            signingConfig = signingConfigs.getByName(BuildType.debug)
        }

        getByName(BuildType.release) {
            isDebuggable = false
            isMinifyEnabled = false
            ndk {
                setAbiFilters(listOf("armeabi-v7a"))
            }
            signingConfig = signingConfigs.getByName(BuildType.release)
        }
    }

Với khai báo này các thiết bị ARMv5 / v6 sẽ không tương thích với phiên bản apk này, hoặc nếu bạn chỉ muốn hỗ trợ "x86" thì các thiết bị MOVBE or SSE4. sẽ không tương thích với phiên bản apk đó. Các bạn cũng có thể khai báo nhiều loại cũng lúc ví dụ như:

android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a', 'x86_64'
        }
    }
}

Với khai báo này thiết bị sẽ hỗ trợ hỗ trợ kiến trúc 64-bit AArch64 và x86 64bit.

4. Các quy tắc khi sử dụng multiple apk.

Trước khi bạn xuất bản nhiều APK cho ứng dụng của mình, bạn cần hiểu các quy tắc sau:

  • Tất cả các APK bạn xuất bản cho cùng một ứng dụng phải có cùng tên gói và được ký với cùng một khóa chứng chỉ.
  • Mỗi APK phải có mã phiên bản khác nhau, được chỉ định bởi thuộc tính android: versionCode.
  • Mỗi APK không được khớp chính xác với sự hỗ trợ cấu hình của APK khác. Nghĩa là, mỗi APK phải khai báo hỗ trợ khác nhau cho ít nhất một trong các thuộc tính lọc Google Play được hỗ trợ (được liệt kê ở trên). Thông thường, bạn sẽ phân biệt APK của mình dựa trên một đặc điểm cụ thể (chẳng hạn như các định dạng nén kết cấu được hỗ trợ) và do đó, mỗi APK sẽ khai báo hỗ trợ cho các thiết bị khác nhau. Tuy nhiên, bạn có thể xuất bản nhiều APK chồng lên nhau một chút về vài đặc điểm khai báo . Khi hai APK trùng nhau (chúng hỗ trợ một số cấu hình thiết bị giống nhau), bị chạy trong điều kiẹn thoả mãn cả hai bản apk đó đó sẽ nhận được APK có mã phiên bản cao hơn (được xác định bởi android: versionCode).
  • VersionCode cho phiên bản sau phải cao hơn phiên bản trước, nếu bạn set thấp hơn bạn sẽ không thể tiến hành cập nhật ứng dụng được
  • Apk yêu cầu api level cao hơn thì cũng tương ứng với việc khai báo versionCode cao hơn.

5. Tổng kết.

Trên đây mình đã giới thiệu sơ qua về Multiple APK support trong Android. Tuy nhiên để có thể làm được thì còn phải tìm hiểu thêm, trên đây mình chỉ giới thiệu cơ bản để các bạn tìm hiểu thêm. Cảm ơn các bạn đã theo dõi bài viết. Các bạn cũng có thể tham khảo nguồn tại trang https://developer.android.com/guide