Tạo nhiều tệp APK với một số phương diện

Nếu bạn phát hành ứng dụng lên Google Play thì bạn nên tạo và tải một Android App Bundle lên. Khi bạn làm như vậy, Google Play sẽ tự động tạo và phân phát các tệp APK được tối ưu hoá cho cấu hình thiết bị của mỗi người dùng, vì vậy, họ chỉ tải mã và tài nguyên mà họ cần để chạy ứng dụng. Việc phát hành nhiều tệp APK rất hữu ích nếu bạn hiện chưa phát hành ứng dụng lên Google Play, nhưng bạn phải tự xây dựng, ký và quản lý từng tệp APK.

Khi phát triển ứng dụng Android để tận dụng nhiều tệp APK trên Google Play, bạn cần áp dụng một số phương pháp hay ngay từ đầu và ngăn chặn những vấn đề không cần thiết trong quá trình phát triển. Bài học này sẽ hướng dẫn bạn cách tạo nhiều APK của ứng dụng, mỗi APK bao gồm một lớp kích thước màn hình khác nhau. Bạn cũng sẽ có được một số công cụ cần thiết để việc duy trì nhiều cơ sở mã APK suôn sẻ nhất có thể.

Xác nhận rằng bạn cần nhiều tệp APK

Khi cố gắng tạo một ứng dụng hoạt động trên rất nhiều thiết bị Android hiện có, đương nhiên là bạn sẽ muốn ứng dụng của mình trông đẹp nhất trên từng thiết bị. Bạn muốn tận dụng không gian của màn hình lớn nhưng vẫn hoạt động trên màn hình nhỏ, để sử dụng các tính năng API Android mới hoặc hoạ tiết trực quan có sẵn trên các thiết bị tiên tiến chứ không phải bỏ những thiết bị cũ. Ngay từ đầu, có vẻ như giải pháp tốt nhất là hỗ trợ nhiều APK, nhưng thường không phải như vậy. Phần Sử dụng một tệp APK thay thế trong hướng dẫn về nhiều tệp APK cung cấp một số thông tin hữu ích về cách hoàn thành tất cả những điều trên bằng một tệp APK duy nhất, bao gồm cả việc sử dụng thư viện hỗ trợ và đường liên kết đến các tài nguyên trong Hướng dẫn cho nhà phát triển Android.

Nếu bạn có thể quản lý ứng dụng đó, việc giới hạn ứng dụng trong một tệp APK duy nhất sẽ có một số lợi ích như sau:

  • Xuất bản và thử nghiệm dễ dàng hơn
  • Chỉ có một cơ sở mã duy nhất
  • Ứng dụng của bạn có thể thích ứng với các thay đổi về cấu hình thiết bị
  • Tính năng khôi phục ứng dụng trên các thiết bị vẫn hoạt động
  • Bạn không phải lo lắng về mức độ ưu tiên của thị trường, hành vi từ việc "nâng cấp" từ APK này lên APK tiếp theo hay APK nào sẽ đi kèm với loại thiết bị nào

Phần còn lại của bài học này giả định rằng bạn đã nghiên cứu chủ đề, chuyên sâu nghiên cứu tài liệu trong các tài nguyên được liên kết và xác định rằng nhiều APK là đường dẫn phù hợp cho ứng dụng của bạn.

Lập biểu đồ các yêu cầu của bạn

Hãy bắt đầu bằng cách tạo một biểu đồ đơn giản để nhanh chóng xác định số lượng tệp APK bạn cần và kích thước màn hình của mỗi tệp APK. Thật may là bạn có thể dễ dàng phác thảo các yêu cầu của mình một cách nhanh chóng, dễ dàng và có tài liệu tham khảo dễ dàng để xem sau. Giả sử bạn muốn phân tách các tệp APK thành hai chiều là API và kích thước màn hình. Tạo bảng có một hàng và cột cho từng cặp giá trị có thể có, đồng thời màu trong một số "blob", mỗi màu đại diện cho một tệp APK.

3 4 5 6 7 8 9 10 11 12 +
nhỏ
bình thường
lớn
xlarge

Ở trên là ví dụ về 4 tệp APK. Màu xanh dương dành cho tất cả các thiết bị màn hình nhỏ/bình thường, Màu xanh lục dành cho thiết bị màn hình lớn và màu đỏ dành cho thiết bị có màn hình cực lớn, tất cả đều có phạm vi API từ 3 đến 10. Màu tím là một trường hợp đặc biệt vì dành cho mọi kích thước màn hình, nhưng chỉ dành cho API 11 trở lên. Quan trọng hơn, chỉ cần xem qua biểu đồ này, bạn sẽ ngay lập tức biết APK nào bao gồm bất kỳ kết hợp API/kích thước màn hình nào. Để khởi động, bạn cũng có các tên mã nổi bật cho từng cái, vì "Chúng tôi đã kiểm tra màu đỏ trên ?" sẽ dễ dàng hơn để hỏi cubie của bạn so với "Chúng tôi đã kiểm tra APK lớn từ 3 đến 10 so với Xoom chưa?" In biểu đồ này và đưa cho tất cả người đang làm việc trên cơ sở mã của bạn. Cuộc sống trở nên dễ dàng hơn rất nhiều.

Đặt tất cả mã và tài nguyên phổ biến vào dự án thư viện

Cho dù bạn đang sửa đổi một ứng dụng Android hiện có hay tạo một ứng dụng từ đầu, đây là việc đầu tiên bạn nên làm đối với cơ sở mã và là điều quan trọng nhất. Bạn chỉ cần cập nhật mọi thứ trong dự án thư viện một lần (ví dụ: các chuỗi được bản địa hoá theo ngôn ngữ, giao diện màu, lỗi được sửa trong mã dùng chung), giúp cải thiện thời gian phát triển và giảm khả năng xảy ra lỗi.

Lưu ý: Mặc dù chi tiết triển khai về cách tạo và thêm dự án thư viện nằm ngoài phạm vi của bài học này, nhưng bạn có thể tăng tốc bằng cách đọc nội dung Tạo thư viện Android.

Nếu bạn đang chuyển đổi một ứng dụng hiện có để sử dụng tính năng hỗ trợ nhiều APK, hãy tìm kiếm cơ sở mã của mọi tệp chuỗi đã bản địa hoá, danh sách giá trị, màu giao diện, biểu tượng trình đơn và bố cục không thay đổi trong các tệp APK rồi đưa tất cả vào dự án thư viện. Mã không thay đổi nhiều cũng sẽ được đưa vào dự án thư viện. Có thể bạn sẽ phải mở rộng các lớp này để thêm một hoặc hai phương thức từ APK sang APK.

Mặt khác, nếu bạn đang tạo ứng dụng từ đầu, hãy cố gắng viết mã trong dự án thư viện trước tiên nhiều nhất có thể, sau đó chỉ chuyển mã xuống một APK riêng lẻ nếu cần. Điều này sẽ dễ quản lý về lâu dài hơn nhiều so với việc thêm blob này vào một, rồi đến một lần khác, rồi nhiều tháng sau đó cố gắng tìm hiểu xem liệu blob này có thể được di chuyển lên phần thư viện mà không cần sửa đổi bất cứ điều gì hay không.

Tạo dự án APK mới

Nên có một dự án Android riêng cho từng APK mà bạn sẽ phát hành. Để dễ dàng sắp xếp, hãy đặt dự án thư viện và tất cả dự án APK liên quan vào cùng một thư mục mẹ. Ngoài ra, hãy nhớ rằng mỗi tệp APK cần có cùng tên gói, mặc dù các tệp APK này không nhất thiết phải chia sẻ tên gói với thư viện. Nếu bạn có 3 tệp APK theo lược đồ được mô tả trước đó, thì thư mục gốc của bạn có thể có dạng như sau:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-purple
foo-red

Sau khi tạo các dự án, hãy thêm dự án thư viện đó làm tệp tham chiếu đến từng dự án APK. Nếu có thể, hãy xác định Hoạt động bắt đầu trong dự án thư viện và mở rộng Hoạt động đó trong dự án APK. Việc xác định hoạt động khởi động trong dự án thư viện sẽ giúp bạn có thể đưa tất cả hoạt động khởi chạy ứng dụng của mình vào cùng một nơi để mỗi tệp APK riêng lẻ không phải triển khai lại các tác vụ "chung" như khởi chạy Analytics, chạy các bước kiểm tra giấy phép và mọi quy trình khởi chạy khác không thay đổi nhiều từ APK sang APK.

Điều chỉnh tệp kê khai

Khi người dùng tải một ứng dụng sử dụng nhiều tệp APK thông qua Google Play, hệ thống sẽ chọn đúng tệp APK cần dùng qua 2 quy tắc đơn giản:

  • Tệp kê khai phải cho thấy rằng APK cụ thể đó đủ điều kiện
  • Trong số các APK đủ điều kiện, số phiên bản cao nhất sẽ chiến thắng.

Ví dụ: hãy lấy tập hợp nhiều tệp APK được mô tả trước đó và giả định rằng mỗi tệp APK đã được thiết lập để hỗ trợ tất cả các kích thước màn hình lớn hơn kích thước màn hình "mục tiêu". Hãy cùng xem biểu đồ mẫu ở phần trước:

3 4 5 6 7 8 9 10 11 12 +
nhỏ
bình thường
lớn
xlarge

Vì mức độ sử dụng có thể trùng lặp, chúng ta có thể mô tả khu vực được bao phủ bởi từng tệp APK như sau:

  • Màu xanh dương bao phủ mọi màn hình, minSDK 3.
  • Màu xanh lục bao phủ màn hình lớn trở lên, minSDK 3.
  • Màu đỏ bao phủ màn hình Rất lớn (thường là máy tính bảng), minSDK là 9.
  • Màu tím bao gồm mọi màn hình, minSDK là 11.

Lưu ý rằng có nhiều điểm trùng lặp trong các quy tắc đó. Ví dụ: một thiết bị rất lớn có API 11 có thể chạy bất kỳ tệp nào trong số 4 tệp APK đã chỉ định. Tuy nhiên, bằng cách sử dụng quy tắc "số phiên bản cao nhất sẽ chiến thắng", chúng ta có thể đặt thứ tự ưu tiên như sau:

Tía ≥ Đỏ ≥ Xanh lục ≥ Xanh dương

Tại sao lại cho phép toàn bộ nội dung trùng lặp? Hãy giả sử APK màu tím có một số yêu cầu mà hai APK còn lại thì không. Trang Bộ lọc trên Google Play trong Hướng dẫn cho nhà phát triển Android có một danh sách đầy đủ các nguyên nhân có thể xảy ra. Ví dụ: Giả sử màu Tím yêu cầu máy ảnh mặt trước. Trên thực tế, điểm mấu chốt của Purple là sử dụng những thứ mang tính giải trí bằng máy ảnh mặt trước! Tuy nhiên, hoá ra là không phải tất cả thiết bị API 11 trở lên đều CÓ máy ảnh mặt trước! Thật đáng kinh ngạc!

Thật may là nếu người dùng đang duyệt Google Play trên một thiết bị như vậy, Google Play sẽ xem xét các tệp kê khai, thấy rằng Purple yêu cầu máy ảnh mặt trước và lặng lẽ bỏ qua yêu cầu đó, khi xác định rằng Purple và thiết bị đó không phải là một kết hợp hoàn hảo giữa thiên văn kỹ thuật số. Sau đó, Red sẽ thấy rằng Red không chỉ tương thích với các thiết bị cực lớn mà còn không quan tâm đến việc có camera mặt trước hay không! Người dùng vẫn có thể tải ứng dụng xuống từ Google Play, vì bất chấp toàn bộ rủi ro xảy ra với máy ảnh trước, vẫn có một tệp APK hỗ trợ cấp độ API cụ thể đó.

Để đảm bảo tất cả tệp APK của bạn luôn nằm trên "kênh phát hành" riêng biệt, bạn phải có một lược đồ mã phiên bản phù hợp. Bạn có thể tìm thấy mã phiên bản được đề xuất trên mục Mã phiên bản trong hướng dẫn cho nhà phát triển của chúng tôi. Bạn nên đọc toàn bộ phần này, nhưng ý chính cơ bản là dành cho tập hợp tệp APK này, chúng ta sẽ sử dụng 2 chữ số biểu thị cho minSDK, 2 chữ số biểu thị kích thước màn hình tối thiểu/tối đa và 3 là số bản dựng. Bằng cách đó, khi thiết bị nâng cấp lên phiên bản Android mới (chẳng hạn như từ 10 lên 11), thiết bị sẽ xem mọi tệp APK hiện đủ điều kiện và được ưu tiên hơn so với tệp hiện được cài đặt là một "bản nâng cấp". Lược đồ số phiên bản, khi được áp dụng cho tập hợp tệp APK mẫu, có thể có dạng như sau:

Xanh lam: 0304001, 0304002, 0304003...
Màu xanh lục: 0334001, 0334002, 0334003
Màu đỏ: 0344001, 0344002, 0344003...
Màu tím: 1104001, 1104002, 1104003...

Kết hợp tất cả lại với nhau, tệp kê khai Android của bạn có thể sẽ có dạng như sau:

Màu lam:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0304001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Màu lục:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0334001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Màu đỏ:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="0344001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="3" />
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="false"
        android:xlargeScreens="true" />
    ...

Tím:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1104001" android:versionName="1.0" package="com.example.foo">
    <uses-sdk android:minSdkVersion="11" />
    <supports-screens android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

Xin lưu ý rằng về mặt kỹ thuật, nhiều tệp APK sẽ hoạt động với thẻ màn hình hỗ trợ hoặc thẻ màn hình tương thích. Màn hình hỗ trợ thường được ưa thích và thường là một ý tưởng không nên sử dụng cả hai. Điều này khiến mọi thứ trở nên phức tạp một cách không cần thiết và làm tăng khả năng xảy ra lỗi. Ngoài ra, xin lưu ý rằng thay vì tận dụng các giá trị mặc định (kích thước nhỏ và bình thường luôn đúng theo mặc định), tệp kê khai sẽ đặt giá trị rõ ràng cho từng kích thước màn hình. Điều này có thể giúp bạn không phải chờ đợi lâu – Ví dụ: tệp kê khai có SDK mục tiêu < 9 sẽ tự động đặt cực đại thành false, vì kích thước đó chưa tồn tại. Vì vậy, hãy nêu rõ ràng!

Xem danh sách kiểm tra trước khi ra mắt

Trước khi tải lên Google Play, hãy kiểm tra kỹ các mục sau. Hãy nhớ rằng các thử nghiệm này liên quan cụ thể đến nhiều APK và không hề đại diện cho danh sách kiểm tra hoàn chỉnh cho tất cả ứng dụng được tải lên Google Play.

  • Tất cả tệp APK phải có cùng tên gói.
  • Tất cả các APK đều phải được ký bằng cùng một chứng chỉ.
  • Nếu các tệp APK trùng lặp trong phiên bản nền tảng, thì tệp có minSdkVersion cao hơn phải có mã phiên bản cao hơn.
  • Mọi kích thước màn hình mà bạn muốn APK hỗ trợ, hãy đặt thành true trong tệp kê khai. Mọi kích thước màn hình bạn muốn tránh, hãy đặt thành false.
  • Kiểm tra kỹ bộ lọc tệp kê khai của bạn để tìm thông tin xung đột (APK chỉ hỗ trợ cupcake trên màn hình XLARGE sẽ không hiển thị cho bất kỳ ai)
  • Tệp kê khai của mỗi tệp APK phải là duy nhất trên ít nhất một trong số các phiên bản màn hình, hoạ tiết OpenGL hoặc nền tảng được hỗ trợ.
  • Thử thử nghiệm từng tệp APK trên ít nhất một thiết bị. Ngoài ra, bạn còn có một trong những trình mô phỏng thiết bị dễ tuỳ chỉnh nhất trên cỗ máy phát triển. Câu đố thôi!

Bạn cũng nên kiểm tra APK đã biên dịch trước khi phát hành ra thị trường, để đảm bảo không có bất kỳ sự bất ngờ nào có thể ẩn ứng dụng của bạn trên Google Play. Việc này thực sự khá đơn giản bằng cách sử dụng công cụ "aapt". Aapt (Công cụ đóng gói tài nguyên Android) là một phần của quy trình xây dựng để tạo và đóng gói ứng dụng Android, đồng thời cũng là công cụ rất tiện dụng để kiểm tra chúng.

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

Khi bạn kiểm tra đầu ra aapt, hãy nhớ kiểm tra để chắc chắn rằng bạn không có các giá trị xung đột cho màn hình hỗ trợ và màn hình tương thích, đồng thời không có các giá trị "uses-feature" ngoài ý muốn được thêm vào do các quyền bạn đặt trong tệp kê khai. Trong ví dụ trên, APK sẽ không hiển thị với hầu hết, nếu không phải tất cả thiết bị.

Tại sao? Bằng cách thêm quyền bắt buộc GỬI_SMS, yêu cầu tính năng của android.hardware.telephony đã được hoàn toàn thêm vào. Vì hầu hết (nếu không phải tất cả) các thiết bị cực lớn đều là máy tính bảng không có phần cứng điện thoại, nên Google Play sẽ lọc ra tệp APK này trong những trường hợp này, cho đến khi các thiết bị trong tương lai xuất hiện, cả hai đều đủ lớn để báo cáo là có kích thước màn hình cực lớn và có phần cứng điện thoại.

Rất may là bạn có thể dễ dàng khắc phục vấn đề này bằng cách thêm đoạn mã sau vào tệp kê khai:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

Yêu cầu android.hardware.touchscreen cũng được thêm ngầm. Nếu muốn APK của mình hiển thị trên TV là thiết bị không phải màn hình cảm ứng, bạn nên thêm đoạn mã sau vào tệp kê khai:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

Sau khi bạn hoàn tất danh sách kiểm tra trước khi phát hành, hãy tải APK của bạn lên Google Play. Có thể mất một chút thời gian để ứng dụng xuất hiện khi duyệt Google Play, nhưng khi ứng dụng xuất hiện, hãy kiểm tra lần cuối. Tải ứng dụng xuống bất kỳ thiết bị thử nghiệm nào mà bạn có thể phải thực hiện để đảm bảo rằng các APK đang nhắm mục tiêu đến các thiết bị mục tiêu. Xin chúc mừng, bạn đã hoàn tất!