Chuyển đến nội dung

Mổ xẻ lỗi bản dựng

Ứng dụng phải hỗ trợ kích thước trang bộ nhớ 16 KB: cách khắc phục

Play Console gắn cờ đúng một điều mà không nói ai là chủ: có một thư viện native bên trong bundle của bạn vẫn được dựng cho trang bộ nhớ 4 KB. Bài viết này tìm ra đúng tệp .so đó, cho bạn biết phụ thuộc nào đã mang nó vào, đưa ra cách sửa ngắn nhất cho framework của bạn, và trao cho bạn những câu lệnh chứng minh bản dựng đã sạch trước khi bạn tải lên lần nữa.

01/02/2027 Bắt đầu chặn phát hành
API 35+ Phạm vi, thiết bị 64 bit
2**14 Căn chỉnh ELF tối thiểu
.so Kiểm tra mã native trước

Hạn chót nào thực sự còn hiệu lực

Giai đoạn cảnh báo, chưa chặn phát hành
161 Ngày còn lại trước khi bản cập nhật chưa đạt yêu cầu bị chặn
2 Hai mốc cũ bạn có thể đã đọc, cả hai đều đã bị thay thế
01/11/2025 ban đầu 31/05/2026 gia hạn 01/02/2027 hiện hành Hôm nay

Trang hiện hành của Google, cập nhật lần cuối ngày 5 tháng 8 năm 2026, nói rằng ứng dụng nhắm tới Android 15 (cấp độ API 35) trở lên phải hỗ trợ kích thước trang bộ nhớ 16 KB trên thiết bị 64 bit, và kể từ ngày 1 tháng 2 năm 2027 bạn sẽ không phát hành được các bản cập nhật chưa đáp ứng. Nếu một kết quả tìm kiếm báo bạn ngày 1 tháng 11 năm 2025 hay ngày 31 tháng 5 năm 2026, thì bài đó viết trước khi mốc thời gian dời đi.

Trả lời nhanh

Google Play yêu cầu ứng dụng nhắm tới Android 15 (cấp độ API 35) trở lên phải hỗ trợ kích thước trang bộ nhớ 16 KB trên thiết bị 64 bit, và kể từ ngày 1 tháng 2 năm 2027 bạn sẽ không phát hành được bản cập nhật nào chưa đáp ứng. Ứng dụng chỉ viết bằng Java hoặc Kotlin, kể cả toàn bộ thư viện và SDK bên trong, thì vốn đã đạt yêu cầu. Ứng dụng có đóng gói thư viện native .so sẽ còn lỗi cho tới khi từng tệp đó được dựng lại hoặc thay thế, tốt nhất là bằng Android Gradle Plugin 8.5.1+NDK r28+, rồi bản dựng vượt qua hai phép kiểm tra riêng biệt: mọi phân đoạn LOAD của ELF căn chỉnh ở ít nhất 2**14, và app bundle báo PAGE_ALIGNMENT_16K. Nâng phiên bản framework không phải là bằng chứng; sản phẩm dựng ra mới là. Nếu việc xử lý cảnh báo này làm đình trệ một đợt thử nghiệm khép kín (closed testing) bạn đang chạy dở, PrimeTestLab giữ cho phía tester tiếp tục chạy trong lúc bạn dựng lại.

Cảnh báo thì ngắn, cùng lắm chỉ nêu một tên tệp, và nó xuất hiện đúng lúc bạn tưởng bản dựng đã xong. Vì thế mà ba nước đi sai giống hệt nhau cứ lặp lại: nhà phát triển tin vào một hạn chót đã dời, nâng phiên bản framework rồi cho là xong việc, hoặc kiểm tra một tệp APK cục bộ mà chẳng bao giờ nhìn tới bundle mà Google thực sự dựng từ đó. Bài viết này được sắp xếp theo đúng cách vấn đề thực sự được giải quyết, tức là nhận diện, truy nguyên, sửa chữa rồi chứng minh, và mọi nội dung trong đây còn đúng tính đến ngày 5 tháng 8 năm 2026, đã đối chiếu với hướng dẫn kích thước trang của Google đúng vào ngày trang đó được cập nhật lần cuối. Ở những chỗ bằng chứng chỉ là trình theo dõi lỗi của người bảo trì chứ không phải ghi chú phát hành chính thức, trang này nói rõ điều đó ngay trên thẻ thay vì làm tròn thành sự thật.

Khắc phục trong ba bước

Mọi cách sửa lỗi này cho ra kết quả thật đều là ba nước đi giống nhau theo cùng một thứ tự: nhận diện thư viện native chưa căn chỉnh, cập nhật phụ thuộc sở hữu nó, rồi chứng minh sản phẩm bạn sắp tải lên. Nhảy thẳng sang bước hai chính là lý do rất nhiều nhà phát triển nâng phiên bản framework, dựng lại, rồi ngồi nhìn cảnh báo quay về y nguyên.

Bản thân yêu cầu này rất hẹp. Hướng dẫn kích thước trang của Google nói rằng ứng dụng nhắm tới Android 15 (cấp độ API 35) trở lên phải hỗ trợ kích thước trang bộ nhớ 16 KB trên thiết bị 64 bit, và kể từ ngày 1 tháng 2 năm 2027 bạn sẽ không phát hành được các bản cập nhật chưa đáp ứng. Nó chỉ áp dụng cho mã native. Nếu ứng dụng của bạn cùng mọi thư viện và SDK bên trong đều thuần Java hoặc Kotlin, Google khẳng định ứng dụng của bạn đã hỗ trợ thiết bị 16 KB. Rắc rối nằm ở chỗ phần lớn nhà phát triển thấy cảnh báo này đều tin mình thuộc nhóm đó, mà thực ra thì không.

01

Nhận diện tệp .so bị lỗi

Mở tệp APK phát hành trong Android Studio qua Build > Analyze APK..., mở rộng lib/arm64-v8alib/x86_64, rồi đọc cột Alignment. Ghi lại mọi tên tệp bị gắn cờ. Những tên tệp đó là khóa tìm kiếm đáng tin cậy duy nhất bạn có.

Mở các công cụ tìm kiếm
02

Cập nhật thứ đang sở hữu nó

Tệp nhị phân do bạn tự biên dịch thì bộ công cụ của bạn sửa được: AGP 8.5.1 trở lên cùng NDK r28 trở lên. Tệp nhị phân đi kèm một plugin, SDK, engine hay AAR thì chỉ người dựng ra nó mới sửa được, nên việc cần làm là nâng cấp, thay thế, hoặc yêu cầu gói đó cung cấp bản đã dựng lại.

Tìm lối ngắn nhất cho framework của bạn
03

Chứng minh sản phẩm, không phải bản nâng cấp

Hai phép kiểm tra độc lập phải cùng đạt. Mọi phân đoạn LOAD của ELF phải căn chỉnh ở 2**14 trở lên, và bundletool phải báo PAGE_ALIGNMENT_16K cho bundle phát hành. Đạt cái này không chứng minh được gì về cái kia.

Tạo các lệnh kiểm tra

Toàn bộ quyết định gói gọn trong một màn hình

Trước khi động vào bất kỳ số phiên bản phụ thuộc nào, hãy đi qua cây này. Nó tốn khoảng hai phút và là khác biệt giữa sửa đúng chỗ với nâng cấp mười một gói vốn chưa bao giờ là vấn đề.

Tệp APK phát hành có thư mục lib chứa tệp .so không?

Không

Vốn đã đạt yêu cầu

Không có mã native trong tệp APK. Google khẳng định ứng dụng chỉ dùng Java hoặc Kotlin, kể cả thư viện và SDK bên trong, thì đã hỗ trợ thiết bị 16 KB. Vẫn nên chạy thử một lượt, và nên xác nhận rằng bản dựng bạn kiểm tra chính là bản bạn đã tải lên.

APK Analyzer hoặc check_elf_alignment.sh có nêu tên thư viện chưa căn chỉnh không?

Truy nguyên rồi mới nâng cấp

Tìm xem framework, plugin, SDK hay engine nào cung cấp đúng tên tệp đó rồi cập nhật gói ấy. NDK của riêng bạn không viết lại được tệp nhị phân dựng sẵn của người khác.

Không

bundletool dump config báo gì cho bundle phát hành?

4K

PAGE_ALIGNMENT_4K

Thư viện thì ổn nhưng cách đóng gói thì không. Hãy chuyển lên AGP 8.5.1 trở lên rồi dựng lại, hoặc dùng cách chữa cháy đóng gói kiểu cũ nếu bạn chưa nâng cấp được.

16K

PAGE_ALIGNMENT_16K

Cách đóng gói đã đúng. Giờ hãy thử các tệp APK do Play sinh ra trên một môi trường 16 KB thật và rà soát mọi đoạn mã lúc chạy đang giả định kích thước trang cố định.

Cái bẫy gói trong một câu

Một tệp APK cục bộ vượt qua mọi phép kiểm tra căn chỉnh không chứng minh được bundle bạn đã tải lên là đúng. Google cảnh báo cụ thể rằng Android Gradle Plugin 8.3 đến 8.5 có thể tạo ra bundle mà các tệp APK do Play dựng từ đó lại không được căn chỉnh ZIP đúng cách, ngay cả khi tệp APK trên máy bạn trông hoàn hảo. Sự lệch pha đó là nguyên nhân phổ biến nhất khiến cảnh báo sống sót qua một lần sửa tưởng là "thành công".

Cảnh báo trong Play Console thực sự nghĩa là gì

Hệ quả mà Google ghi thành văn rất chính xác: kể từ ngày 1 tháng 2 năm 2027 bạn sẽ không phát hành được bản cập nhật nhắm tới Android 15 (cấp độ API 35) trở lên mà thiếu hỗ trợ 16 KB. Đó là một rào chặn phát hành đối với bản cập nhật, chứ không phải lời khẳng định rằng ứng dụng đã đăng sẽ bị gỡ khỏi cửa hàng vào ngày đó. Từ giờ tới lúc ấy, phần lớn nhà phát triển chỉ thấy một cảnh báo tương thích chứ không phải một lần từ chối tải lên.

Câu chữ rất quan trọng, vì phiên bản hoảng loạn của câu chuyện này lan nhanh hơn phiên bản chính xác. Hãy đọc đúng những dòng chữ Google thật sự hiển thị, và phạm vi trở nên hẹp lại và xử lý được.

Play Console · App bundle details

App must support 16 KB memory page sizes

Action by Feb 1, 2027
Consequence You won't be able to release app updates
Also shown Extension granted

Tái hiện từ ảnh chụp Play Console mà chính Google đăng trong hướng dẫn kích thước trang. Các nhãn giữ nguyên tiếng Anh đúng như trong ảnh chụp đó: Console của bạn có thể hiển thị chúng bằng tiếng Việt, và bố cục cùng các nút khả dụng có thể khác nhau tùy tài khoản.

Có hai cách hiểu thường sai về thẻ đó. Thứ nhất, "Action by Feb 1, 2027" không phải là đồng hồ đếm ngược tới lúc bị xóa; chính văn bản của Google trên cùng trang mô tả kết quả là bạn không phát hành được các bản cập nhật đó. Thứ hai, dòng Extension granted có xuất hiện trong ảnh chụp của Google, nhưng điều đó không xác lập rằng hiện có một quy trình xin gia hạn đang mở cho bạn. Chỉ coi việc gia hạn là có thật khi bạn nhìn thấy tùy chọn đó ngay trong Play Console của mình.

Bạn thực sự đã đọc hạn chót nào?

Có ba mốc đang lan truyền và chỉ một mốc còn hiệu lực. Hãy chọn mốc bạn từng thấy, công cụ này sẽ xác định trạng thái của nó so với trang Google hiện hành, vốn được cập nhật lần cuối vào ngày 5 tháng 8 năm 2026.

Công cụ 01

Trình xác định hạn chót

Chọn một mốc để xem mốc đó còn hiệu lực hay không.

Google đã dời hạn chót này hơn một lần. Trước khi bạn lập kế hoạch phát hành quanh ngày 1 tháng 2 năm 2027, hãy tự mở hướng dẫn kích thước trang và kiểm tra dấu "Last updated" ở cuối trang. Chỉ một thói quen đó thôi đã đáng giá hơn bất kỳ mốc thời gian nào in trong một bài viết, kể cả bài này.

Yêu cầu 16 KB có ảnh hưởng tới ứng dụng của tôi không?

Framework của bạn không quyết định điều này. Nội dung tệp APK sinh ra mới quyết định. Nếu có tệp .so nằm dưới lib thì bạn nằm trong phạm vi, bất kể bạn có bao giờ mở một tệp C++ hay chưa, còn nếu không có tệp nào thì chính hướng dẫn của Google nói rằng bạn đã hỗ trợ thiết bị 16 KB.

Ứng dụng thuần Java hoặc Kotlin

Google nói rất rõ ở điểm này: nếu ứng dụng của bạn cùng toàn bộ thư viện và SDK trong đó chỉ dùng Java hoặc Kotlin, ứng dụng của bạn đã hỗ trợ thiết bị 16 KB. Google vẫn khuyên nên thử trong môi trường 16 KB để bắt các lỗi thoái lui ngoài dự tính, và việc đó chỉ tốn của bạn một lượt chạy máy ảo.

Cái bẫy nằm ở cụm "cùng toàn bộ thư viện và SDK trong đó". Chỉ một phụ thuộc về cơ sở dữ liệu, phân tích, báo lỗi, media, bản đồ, học máy hay bảo mật cũng đủ thêm tệp nhị phân native vào một dự án mà mã nguồn của chính nó không có gì ngoài Kotlin. "Tôi không viết C++" không phải bằng chứng. Thư mục lib mới là bằng chứng.

Flutter, React Native, Unity, Kivy và các công cụ tạo ứng dụng không cần code

Các nền tảng này vốn dĩ đi kèm runtime native, tệp nhị phân của engine và thư viện plugin, nên gần như luôn nằm trong phạm vi. Google nêu đích danh các công cụ tạo ứng dụng bên thứ ba có dùng thư viện native như một cách khiến ứng dụng bị ảnh hưởng ngay cả khi tác giả chưa từng viết C hay C++. Thứ khác nhau không phải là bạn có mã native hay không mà là gói nào đã mang phần đang lỗi vào, và vì thế việc truy nguyên tên tệp phải đi trước mọi lần nâng cấp.

Cách kiểm tra, chính xác từng bước

Android Studio Build Analyze APK... lib/

Mở tệp APK phát hành, mở rộng lib, rồi nhìn các thư mục ABI bên trong, thường là arm64-v8ax86_64. Có bất kỳ tệp shared object nào nghĩa là ứng dụng của bạn dùng mã native. Không có tệp .so và không có thư mục lib nghĩa là tệp APK này hoàn toàn không dùng mã native. Cột Alignment trong trình phân tích hiển thị thông báo cảnh báo cho những tệp có vấn đề căn chỉnh, và đó là con đường nhanh nhất từ "có gì đó sai" tới một cái tên tệp.

Công cụ 02

Phân loại mức ảnh hưởng

01 Ứng dụng của bạn hiện đang nhắm tới đâu?

02 Mở tệp APK phát hành trong APK Analyzer. Có thư mục lib không?

03 Mô tả nào đúng nhất với ứng dụng của bạn?

04 Bạn đã chạy bundletool dump config trên bundle phát hành chưa?

Vì sao tệp nhị phân 4 KB thất bại trên thiết bị 16 KB

Trang bộ nhớ là khối nhỏ nhất mà nhân hệ thống ánh xạ trong một lần. Android xưa nay dùng trang 4 KB; Android 15 bổ sung hỗ trợ cho thiết bị được cấu hình với trang 16 KB. Một thư viện native có ghi lại mức căn chỉnh mà các phân đoạn của nó được liên kết theo, và nếu giá trị đó nhỏ hơn kích thước trang của thiết bị thì trình nạp không thể đặt phân đoạn vào đúng ranh giới trang.

Đó là toàn bộ cơ chế, và nó giải thích con số bạn sẽ gặp đi gặp lại. Căn chỉnh được biểu diễn dưới dạng lũy thừa của hai: 2**12 là 4096 byte, 2**14 là 16384 byte. Quy tắc của Google là mỗi phân đoạn LOAD trong một thư viện native phải căn chỉnh ở 2**14 trở lên. Thư viện dựng ở 2**14 chạy được trên cả thiết bị 4 KB lẫn 16 KB, vì 16384 là bội số chẵn của 4096. Thư viện dựng ở 2**12 chỉ chạy được với kích thước trang nhỏ hơn. Chính sự bất đối xứng đó là lý do cách sửa luôn là "nâng mức căn chỉnh lên" chứ không bao giờ là "phát hiện xem thiết bị nào".

Công cụ 03

Trình mô phỏng trang bộ nhớ

Chọn mức căn chỉnh mà thư viện của bạn báo cáo rồi xem các phân đoạn của nó có thể bắt đầu ở đâu trên thiết bị dùng trang 16 KB.

Đạt

Còn một ràng buộc thứ hai hoàn toàn tách biệt và nằm ngoài thư viện. Các thư viện native lưu ở dạng không nén bên trong tệp APK cũng phải nằm trên ranh giới 16 KB trong chính kho lưu trữ ZIP. Đó là thuộc tính của cách đóng gói, được kiểm tra bằng zipalign và do plugin dựng của bạn cấu hình, và nó có thể sai ngay cả khi từng thư viện bên trong đã căn chỉnh hoàn hảo. Giữ hai ý niệm đó tách bạch chính là điều hữu ích nhất bạn có thể mang theo từ mục này.

Cách đọc các con số

Khi bạn thấy 2**14 trong kết quả của llvm-objdump, đó là đạt. 2**13 hay 2**12 là trượt. Không có điểm nửa vời và không có chuyện "gần đủ": chỉ một phân đoạn LOAD chưa căn chỉnh, trong một thư viện, ở một ABI, cũng đủ để giữ cảnh báo lại trên tài khoản của bạn.

Cách sửa ngắn nhất cho từng framework

Mức sẵn sàng của framework và mức đạt yêu cầu của ứng dụng là hai chuyện khác nhau. React Native 0.77 và các phiên bản Unity được hỗ trợ là những mốc có thật, có tài liệu. Flutter thì không có mốc tối thiểu chung nào kiểm chứng được. Trong mọi trường hợp, việc nâng cấp sửa được các tệp nhị phân của chính framework và để lại mọi plugin bên thứ ba nguyên trạng chưa đạt yêu cầu như trước.

Công cụ 04

Trình tìm theo framework

    
                

    Điều gì vẫn có thể sai sau bước này

    Toàn bộ các mốc trong một bảng

    Framework Mốc có tài liệu Hành động ngắn nhất Độ tin cậy
    Flutter Không có mốc tối thiểu chung được kiểm chứng; 3.38 là cột mốc chuẩn bị có tài liệu (NDK mặc định r28) Flutter ổn định hiện hành, cập nhật plugin native, dọn dẹp, dựng lại, kiểm tra từng thư viện MỘT PHẦN
    React Native 0.77 Lộ trình nâng cấp được hỗ trợ, rồi cập nhật module native và SDK nhà cung cấp ĐÃ KIỂM CHỨNG
    Nhánh Unity 6.1 6000.1 trở lên Nâng editor, cập nhật gói và plugin, dựng lại ĐÃ KIỂM CHỨNG
    Unity 6 LTS 6000.0.38f1 trở lên Như trên ĐÃ KIỂM CHỨNG
    Unity 2022 LTS 2022.3.56f1 trở lên Như trên ĐÃ KIỂM CHỨNG
    Unity 2021 2021.3.48f1 trở lên, cần đủ điều kiện LTS mở rộng Nâng cấp nếu đủ điều kiện, nếu không thì chuyển sang editor được hỗ trợ ĐÃ KIỂM CHỨNG
    Unity Burst 1.8.21 trở lên Nâng Burst khi lib_burst_generated.so bị nêu tên ĐÃ KIỂM CHỨNG
    Android native NDK r28+ với AGP 8.5.1+ Biên dịch lại mã của bạn, cập nhật mọi phụ thuộc dựng sẵn ĐÃ KIỂM CHỨNG
    Kẹt ở NDK cũ r27 trở xuống cùng cả hai tùy chọn linker Thêm max-page-sizecommon-page-size, dựng lại toàn bộ thư viện DÙNG ĐƯỢC, KHÔNG ƯU TIÊN
    Kivy hoặc công cụ Python Không có phiên bản chung nào được kiểm chứng Cập nhật công cụ và công thức dựng, chuyển đúng tên tệp lên nhóm phát triển gốc TÙY NHÀ CUNG CẤP
    Công cụ no-code Không có phiên bản chung nào được kiểm chứng Sinh lại trên hệ dựng đã đạt chuẩn của nhà cung cấp, gửi họ tên tệp TÙY NHÀ CUNG CẤP

    Các nhãn độ tin cậy mang cùng một ý nghĩa ở khắp trang này. ĐÃ KIỂM CHỨNG nghĩa là một nguồn gốc hiện hành nói thẳng điều đó. MỘT PHẦN nghĩa là một nguồn đáng tin đỡ được phần cốt lõi của khẳng định nhưng không đỡ được mọi chi tiết triển khai. ĐƯỢC BÁO CÁO nghĩa là bằng chứng nằm ở trình theo dõi lỗi của người bảo trì hoặc ở báo cáo của nhà phát triển chứ không phải ghi chú phát hành chính thức.

    Tìm đúng thư viện đang gây ra lỗi

    Tên tệp chính là toàn bộ cuộc điều tra. Một khi bạn biết libfoo.so là tệp nhị phân bị lỗi, câu hỏi thôi còn là "làm sao sửa hỗ trợ 16 KB" mà trở thành "gói nào cung cấp libfoo.so, và đã có phiên bản mới hơn chưa". Câu hỏi thứ hai có câu trả lời; câu thứ nhất thì không.

    Bắt đầu từ APK Analyzer

    Mở Build > Analyze APK..., nạp tệp APK phát hành, rồi mở rộng lib. Bên trong bạn sẽ thấy một thư mục cho mỗi ABI, thường là arm64-v8ax86_64. Cột Alignment hiển thị thông báo cảnh báo với những tệp có vấn đề căn chỉnh. Cảnh báo của chính Android Studio và Lint cũng làm nổi bật các thư viện native chưa đạt yêu cầu, nên bạn có thể thấy cùng một phát hiện xuất hiện ở nhiều chỗ.

    Hãy ghi lại mọi tên tệp bị gắn cờ trước khi động vào một số phiên bản nào. Kiểm tra riêng cả hai thư mục ABI: chuyện arm64-v8a đạt trong khi x86_64 trượt, hoặc ngược lại, là hoàn toàn bình thường, vì đó là hai tệp nhị phân khác nhau được dựng bởi những quy trình có thể khác nhau.

    Giải mã kết quả từ dòng lệnh

    Nếu bạn thích làm việc trong terminal, Google cung cấp check_elf_alignment.sh để báo ALIGNED hoặc UNALIGNED cho một tệp APK, và bạn có thể kiểm tra trực tiếp một thư viện bằng llvm-objdump. Cả hai đều cần Android SDK Build-Tools 35.0.0 trở lên. Hãy dán bất cứ thứ gì chúng in ra vào ô bên dưới và công cụ này sẽ đọc lại cho bạn.

    Công cụ 05

    Trình đọc ELF

    Dán kết quả từ llvm-objdump -p tep.so | grep LOAD, check_elf_alignment.sh hoặc zipalign -c -P 16. Mọi thứ được phân tích ngay trong trình duyệt của bạn; không có gì được tải lên đâu cả.

    Hãy dán một ít kết quả rồi nhấn Giải mã.

    Xác định phụ thuộc nào đang sở hữu nó

    Play Console và APK Analyzer đều đưa cho bạn một tên tệp mà không nói ai là chủ. Hãy gõ tên đó vào bên dưới, công cụ này sẽ cho bạn biết những gì đã biết về tệp nhị phân ấy, kèm theo chất lượng bằng chứng, và đưa cho bạn các câu lệnh tìm kiếm đã điền sẵn tên tệp của bạn.

    Công cụ 06

    Tra chủ sở hữu thư viện

    Gõ hoặc chọn một tên tệp để xác định chủ sở hữu có khả năng nhất.

    ./gradlew app:dependencies cho bạn xem đồ thị phụ thuộc đã được giải, và đó là cách bạn tìm ra gói gián tiếp đã kéo vào một thư viện mà bạn chưa bao giờ tự thêm. Nó không nói thẳng cho bạn biết sản phẩm nào chứa một tệp .so nhất định, nên hãy dùng kèm với việc giải nén tệp AAR khả nghi. Đây là những kỹ thuật chẩn đoán thực dụng chứ không phải các bước do Google bắt buộc.

    Kiểm tra app bundle, không chỉ tệp APK cục bộ

    Tệp APK cục bộ của bạn và các tệp APK mà Google Play sinh ra từ bundle của bạn là hai sản phẩm khác nhau. Căn chỉnh ELF nằm bên trong từng thư viện; căn chỉnh ZIP là thuộc tính của cách kho lưu trữ được đóng gói; còn bundle mang theo một cấu hình nói cho Play biết dùng cái nào. Cả ba đều có thể mâu thuẫn nhau, và chỉ cái cuối cùng mới quyết định thứ người dùng cài về.

    Đây là cơ chế đằng sau phiên bản khó chịu nhất của vấn đề: nhà phát triển nâng cấp mọi thứ, kiểm tra tệp APK cục bộ, thấy kết quả sạch, tải lên, và cảnh báo vẫn còn nguyên. Không có thứ nào họ kiểm tra là sai cả. Họ chỉ là chưa bao giờ kiểm tra đúng thứ mà Play đánh giá.

    Thứ bạn đã kiểm tra

    app-release.apk trên máy bạn

    Do Gradle dựng trực tiếp trên phần cứng của bạn, theo hành vi đóng gói của bạn. Vượt qua zipalign ở đây chứng minh tệp này được đóng gói đúng.

    Thứ Play đánh giá

    Các tệp APK sinh ra từ app-release.aab

    Do Google dựng từ bundle của bạn, theo mức căn chỉnh mà bundle yêu cầu. Nếu bundle nói 4 KB thì chúng sai, bất kể tệp APK cục bộ của bạn sạch đến đâu.

    Vậy nên hãy chạy lệnh này trên chính bundle bạn sắp tải lên, lần nào cũng vậy:

    bundletool dump config --bundle=app-release.aab | grep alignment

    PAGE_ALIGNMENT_16K là kết quả bạn muốn. PAGE_ALIGNMENT_4K nghĩa là bundle đang bảo bundletool đóng gói thư viện native theo ranh giới 4 KB, nên mọi tệp APK Play dựng từ đó đều sẽ sai. Google cảnh báo cụ thể rằng Android Gradle Plugin 8.3 đến 8.5 có thể tạo ra đúng sự lệch pha này: bản dựng cục bộ trông đã căn chỉnh, còn ứng dụng mà Play dựng từ bundle lại không cài đặt đúng cách trên thiết bị 16 KB. Cách khắc phục được ưu tiên là chuyển lên Android Gradle Plugin 8.5.1 trở lên.

    Mọi câu lệnh, với tên tệp của chính bạn trong đó

    Gõ tên tệp của bạn một lần. Mọi câu lệnh bên dưới sẽ tự viết lại, và mỗi tab hiển thị đúng kết quả được tính là đạt, nên bạn không bao giờ phải đoán xem kết quả có tốt hay không.

    Công cụ 07

    Phòng lệnh

    
                
    Đạt
    Trượt

    Đừng dừng lại ở "APK Analyzer báo đã căn chỉnh"

    Một lần kiểm tra APK đạt chỉ là một trong bốn phép kiểm tra, không phải vạch đích. Hãy xác nhận căn chỉnh LOAD của ELF, căn chỉnh ZIP của tệp APK, cấu hình bundle, và hành vi lúc chạy của chính sản phẩm mà Play sinh ra. Chỉ cần một trong số đó trượt là đủ để cảnh báo còn nguyên trên tài khoản của bạn sau một bản dựng mà bạn tưởng đã xong.

    AGP, NDK và cái bẫy đóng gói

    Hai con số phiên bản gánh phần lớn công việc. NDK r28 trở lên biên dịch mã native với căn chỉnh 16 KB theo mặc định, và Android Gradle Plugin 8.5.1 trở lên đóng gói các thư viện native không nén đúng theo ranh giới ZIP 16 KB. Không cái nào sửa được một tệp nhị phân biên dịch sẵn đi kèm một phụ thuộc.

    Vùng giữa nguy hiểm là Android Gradle Plugin 8.3 đến 8.5. Trong khoảng đó, một bản dựng tại chỗ có thể trông hoàn toàn đúng trong khi bundletool không căn chỉnh ZIP cho các tệp APK mà nó tạo ra từ bundle của bạn để giao cho Play, và câu chữ của Google về hậu quả rất thẳng: ứng dụng dựng từ bundle đó sẽ không cài đặt đúng cách. Nếu bạn đang ở 8.5.0 và tệp APK cục bộ vượt qua mọi phép kiểm tra bạn nghĩ ra được, thì đây là thứ đầu tiên cần loại trừ.

    Công cụ 08

    Trình kiểm tra toolchain

    
                

    Bảng tra thiết lập bản dựng

    Tình huống Thiết lập Ghi chú
    NDK nên dùng r28 trở lên Tạo ra kết quả native căn chỉnh 16 KB theo mặc định
    AGP nên dùng 8.5.1 trở lên Xử lý thư viện native không nén trên ranh giới ZIP 16 KB
    NDK r27 trở xuống -Wl,-z,max-page-size=16384 Tùy chọn linker bắt buộc trên mọi target native
    NDK r27 trở xuống -Wl,-z,common-page-size=16384 Dùng kèm với tùy chọn kích thước trang tối đa
    ndk-build LOCAL_LDFLAGS += ... Áp dụng cả hai tùy chọn cho từng target native
    CMake target_link_options(...) Áp dụng cả hai tùy chọn cho từng target liên quan
    Chưa nâng cấp được AGP jniLibs.useLegacyPackaging = true Nén thư viện native; làm tăng dung lượng đĩa sau khi cài
    AGP 8.0 trở xuống android.bundle.enableUncompressedNativeLibs=false Thuộc tính cũ bổ sung đi kèm tùy chọn ở trên
    Mã lúc chạy getpagesize() hoặc sysconf(_SC_PAGESIZE) Thay cho giá trị 4096 viết cứng và giả định PAGE_SIZE cố định

    Phần mà việc đóng gói không sửa được

    Nếu chính mã C hoặc C++ của bạn giả định một kích thước trang, không cờ dựng nào cứu bạn được. Hãy bỏ các giá trị 4096 viết cứng và mọi chỗ dựa vào hằng số PAGE_SIZE cố định, truy vấn giá trị thật lúc chạy bằng getpagesize() hoặc sysconf(_SC_PAGESIZE), rồi rà lại mọi lời gọi mmap() cùng mọi tham số mà bạn đang tự căn theo trang bằng tay. Đây là nhóm lỗi khiến ứng dụng cài đặt sạch sẽ trên thiết bị 16 KB, vượt qua các phép kiểm tra bundle, rồi sập ngay lần đầu chạm vào ánh xạ bộ nhớ.

    Thứ tự thao tác

    Hãy sửa phía trình biên dịch trước phía đóng gói. Nếu bạn áp dụng cách đóng gói kiểu cũ trước, tệp APK của bạn sẽ bắt đầu vượt qua zipalign trong khi các thư viện bên trong vẫn được dựng cho trang 4 KB, và bạn đã giấu vấn đề thật sau một kết quả màu xanh.

    Thử trên môi trường 16 KB thật

    Một câu lệnh quyết định phép thử của bạn có ý nghĩa hay không: adb shell getconf PAGE_SIZE phải trả về 16384. Hãy chạy nó trước mỗi buổi thử. Một máy ảo lặng lẽ khởi động ở chế độ 4 KB sẽ cho một bản dựng hỏng vượt qua mọi thứ bạn ném vào nó.

    Bạn có ba lối đi thực dụng và hai lối chuyên biệt. Hãy chọn lối nào bạn thực sự với tới được ngay hôm nay; xét về mục đích bắt lỗi kích thước trang thì chúng không khác nhau về chất lượng.

    Công cụ 09

    Chọn môi trường thử nghiệm

      Giới hạn

      Rồi, lần nào cũng vậy, trước mọi phép thử

      adb shell getconf PAGE_SIZE

      Đừng đi tiếp trừ khi kết quả là 16384.

      Thực sự nên chạy thử những gì

      Khi môi trường đã được xác nhận, lượt thử có ích không phải là "ứng dụng có mở lên không". Lỗi native tụ lại ở những tính năng chạm tới mã native, nên hãy chủ động chạy chúng: khởi động nguội, di chuyển qua các màn hình, camera, đọc ghi cơ sở dữ liệu, phát và ghi media, đăng nhập, tác vụ nền, mọi tính năng học máy hay thực tế tăng cường, mọi bề mặt của plugin native, và mọi phần trong mã của chính bạn có dùng ánh xạ bộ nhớ. Nếu một tính năng chạy trên một trong các thư viện bạn vừa nâng cấp, thì chính tính năng đó là phép thử.

      Chế độ tương thích không phải là đạt

      Android có thể chạy một số ứng dụng căn chỉnh 4 KB trên thiết bị 16 KB thông qua một lối tương thích, và khi đó bạn có thể thấy một cảnh báo ở lần mở đầu tiên. Google vẫn khuyến nghị căn chỉnh 16 KB cho đúng để có độ tin cậy và ổn định tốt nhất. Một ứng dụng chỉ chạy được vì chế độ tương thích can thiệp thì không phải là ứng dụng đã được sửa, và phát hành trên cơ sở đó nghĩa là sự cố thật vẫn còn ở phía trước.

      Vì sao cảnh báo sống sót qua một lần nâng cấp

      Gần như mọi trường hợp "tôi sửa rồi mà" đều rơi vào một trong mười ba tình huống cụ thể, và mười một trong số đó chứng minh được ngay từ sản phẩm đang nằm trước mặt bạn. Hãy chọn triệu chứng khớp nhất, thường bạn sẽ biết nguyên nhân trước cả khi đọc hết.

      Công cụ 10

      Phân loại cảnh báo dai dẳng

      Nguyên nhân khả dĩ nhất

      Hành động nhanh nhất

      Nên tránh

      Hai mục trong số đó xứng đáng có một lời dè dặt thay vì một câu trả lời chắc nịch. Không nguồn gốc nào xác lập Google Play mất bao lâu để xem xét lại một bundle đã tải lên, nên nếu cảnh báo của bạn còn nguyên ngay sau khi tải lên thì cách làm trung thực là xác nhận mã phiên bản mới đã xuất hiện ở mục bản phát hành và app bundle mới nhất rồi kiểm tra lại sau, thay vì tin vào một con số cụ thể nào đó bạn đọc được về thời gian xử lý. Và một ứng dụng chỉ chạy được nhờ chế độ tương thích can thiệp thì không phải đã được sửa, nó chỉ đang được châm chước.

      Những thư viện bên thứ ba cứ xuất hiện lại

      Đây là các ví dụ được báo cáo, không phải bảng xếp hạng mức độ phổ biến, và cũng không phải lời hứa rằng một phiên bản nhất định sẽ sửa được bản dựng của bạn. Một gói có thể thêm, gỡ hoặc thay thế sản phẩm native ở bất kỳ bản phát hành nào. Người quyết định cuối cùng luôn là tệp nhị phân nằm trong bundle phát hành của chính bạn.

      Hãy dùng phần này làm điểm khởi đầu khi một tên tệp trông quen thuộc, rồi đối chiếu với các bản phát hành hiện tại và issue đang mở của dự án đó. Ở đâu bằng chứng chỉ là trình theo dõi lỗi của người bảo trì chứ không phải ghi chú phát hành, thẻ sẽ ghi rõ điều đó.

      Công cụ 11

      Chỉ mục thư viện được báo cáo

      ObjectBox Java CHƯA KIỂM CHỨNG

      libobjectbox-jni.so

      Các thư viện native Android đời cũ thất bại trong môi trường 16 KB. Không có phiên bản đã sửa cụ thể nào được xác nhận đủ chắc để chúng tôi công bố ở đây. Hãy xem ghi chú phát hành hiện tại của ObjectBox để biết phiên bản nào bổ sung hỗ trợ 16 KB, rồi xác nhận bằng chính tệp nhị phân trong tệp APK bạn dựng ra thay vì chỉ tin vào số phiên bản.

      ObjectBox Dart và Flutter CHƯA KIỂM CHỨNG

      thư viện Android đi kèm gói

      SDK Dart của ObjectBox mang theo thư viện Android riêng. Không có phiên bản đã sửa cụ thể nào được xác nhận đủ chắc để chúng tôi công bố ở đây. Hãy xem ghi chú phát hành hiện tại của ObjectBox, rồi kiểm tra đúng sản phẩm mà bản dựng của bạn thực sự chọn.

      Thư viện native sqlite3 ĐƯỢC BÁO CÁO

      libsqlite3.so

      Một phụ thuộc cũ phiên bản 3.43.0 xuất hiện trong các gói Flutter và AWS Amplify bị ảnh hưởng. Bằng chứng từ issue xác định 3.46.1+1 là phiên bản bổ sung hỗ trợ 16 KiB. Hãy kiểm tra phiên bản phụ thuộc thực sự được chọn chứ không chỉ phiên bản bạn khai báo, vì một gói framework có thể ghim lại phiên bản cũ hơn.

      SQLCipher cho Android MỘT PHẦN

      sqlcipher-android

      Gói cũ android-database-sqlcipher đã bị chính nhóm phát triển ngừng hỗ trợ để chuyển sang gói sqlcipher-android đang được bảo trì. Không có phiên bản cụ thể nào được xác nhận đủ chắc để công bố như mốc tối thiểu đã sửa, nên hãy chuyển sang gói đang được bảo trì rồi kiểm tra từng ABI trong ứng dụng bạn dựng ra thay vì tin vào một số phiên bản.

      FFmpegKit và các bản fork CHƯA KIỂM CHỨNG

      tệp nhị phân xử lý media

      Kho FFmpegKit gốc đã ngừng hoạt động, và không có bản phát hành đạt chuẩn nào an toàn phổ quát được xác lập. Chất lượng các bản fork rất khác nhau. Hãy xác định chính xác bản fork nào mà bản dựng của bạn chọn, kiểm tra trực tiếp sản phẩm của từng ABI, và cân nhắc mức độ bảo trì cùng nguồn gốc trước khi lấy nó làm giải pháp.

      Realm JavaScript BÁO CÁO MÂU THUẪN

      tệp nhị phân Realm và JNI

      Các báo cáo mâu thuẫn nhau. Phiên bản 20.1.0 từng bị gắn cờ, rồi một báo cáo sau đó nói 20.2.0 đã sửa được một tệp nhị phân Realm trong khi một tệp nhị phân JNI khác vẫn còn lỗi. Không thể nêu tên một phiên bản an toàn nào một cách có trách nhiệm, nên hãy nâng cấp rồi kiểm tra riêng từng thư viện mà Realm đóng góp.

      MediaPipe Tasks Vision ĐƯỢC BÁO CÁO

      libmediapipe_tasks_vision_jni.so

      Được báo cáo ở mức căn chỉnh 2**12. Trong issue mà chúng tôi tham khảo không có bản phát hành đã sửa nào được xác lập, nên hãy coi tính tương thích là phụ thuộc phiên bản: xem ghi chú phát hành hiện tại, nâng cấp, rồi kiểm tra tệp nhị phân trong bản dựng của chính bạn.

      OpenCV Android ĐƯỢC BÁO CÁO

      sản phẩm OpenCV Android

      Vấn đề căn chỉnh được báo cáo trên một sản phẩm Android của OpenCV 5.0.0. Issue trong kho có nhắc tới một bản sửa ở CI, nhưng không có sản phẩm phát hành cụ thể nào được xác lập an toàn. Hãy tải đúng tệp AAR bạn phụ thuộc vào, giải nén, rồi tự kiểm tra các thư viện bên trong.

      Unity Burst ĐÃ KIỂM CHỨNG

      lib_burst_generated.so

      Hướng dẫn của chính Unity là cập nhật gói Burst lên 1.8.21 trở lên khi tệp này bị gắn cờ. Đây là mục duy nhất trong chỉ mục dựa trên tài liệu chính thức của nhà cung cấp chứ không phải báo cáo issue.

      Unity AR và các plugin khác ĐƯỢC BÁO CÁO

      libUnityARCore.so, libquack.so và những tệp khác

      Báo cáo từ cộng đồng nêu tên những tệp này trong nhóm tệp nhị phân sống sót qua một lần nâng cấp editor. Không có phiên bản chung nào để trích dẫn vì mỗi tệp thuộc về một gói khác nhau. Hãy dùng đúng tên tệp để quyết định phải truy gói nào.

      Vì sao chỉ mục này ngắn: số lượng issue cho thấy dự án nào có người dùng lên tiếng nhiều, chứ không cho thấy thư viện nào được cài đặt nhiều nhất. Công bố một bảng xếp hạng "những thủ phạm phổ biến nhất" chẳng khác nào bịa ra một con số thống kê. Thứ thực sự áp dụng được cho mọi trường hợp là phương pháp: lấy tên tệp, tìm ra gói, kiểm tra các bản phát hành hiện tại của gói đó, rồi kiểm tra tệp nhị phân trong bản dựng của bạn.

      Liên quan thế nào tới hạn chót API 36 ngày 31 tháng 8 năm 2026

      Đây là hai yêu cầu độc lập của Google Play gặp nhau tại đúng một điểm. Nâng cấp độ API mục tiêu có thể làm lộ ra cảnh báo 16 KB, vì yêu cầu này áp dụng cho ứng dụng nhắm tới Android 15 (cấp độ API 35) trở lên. Việc nâng cấp độ đó không tạo ra sự lệch căn chỉnh và cũng không sửa được nó.

      Google Play yêu cầu ứng dụng mới và bản cập nhật ứng dụng phải nhắm tới Android 16 (cấp độ API 36) kể từ ngày 31 tháng 8 năm 2026, kèm khả năng xin gia hạn đến ngày 1 tháng 11 năm 2026. Đó là thay đổi ở tệp manifest và ở hành vi ứng dụng. Còn quy tắc 16 KB là thay đổi về tương thích nhị phân. Nhà phát triển nâng targetSdk vào thứ Hai rồi thấy cảnh báo 16 KB vào thứ Ba không hề làm hỏng thứ gì: các thư viện native vốn đã được dựng cho trang 4 KB, và cấp độ mục tiêu cao hơn chỉ đơn giản đưa ứng dụng vào phạm vi của một phép kiểm tra vốn dĩ sẽ áp dụng.

      Yêu cầu A

      Nhắm tới API 36
      • Ngày 31/08/2026, gia hạn đến 01/11/2026
      • Phạm vi Ứng dụng mới và bản cập nhật ứng dụng
      • Nằm ở Tệp manifest và cấu hình bản dựng của bạn
      • Cách xử lý Nâng cấp độ mục tiêu và xử lý các thay đổi hành vi của Android 16

      Yêu cầu B

      Hỗ trợ kích thước trang 16 KB
      • Ngày 01/02/2027
      • Phạm vi Ứng dụng nhắm API 35+ trên thiết bị 64 bit
      • Nằm ở Các tệp nhị phân native bên trong bundle của bạn
      • Cách xử lý Dựng lại hoặc thay thế mọi thư viện chưa căn chỉnh

      Trên thực tế, hãy xem chúng là một cuộc di chuyển duy nhất với hai bằng chứng. Đằng nào bạn cũng sẽ nâng cấp độ mục tiêu, vậy hãy xếp đợt rà soát thư viện native vào cùng bản phát hành thay vì phát hiện ra giữa lúc chạy nước rút cho API 36. Để xem đầy đủ các cấp độ theo loại thiết bị, các trường hợp ngoại lệ và cơ chế gia hạn của quy tắc API mục tiêu, hãy đọc bài viết của chúng tôi về hạn chót API 36 của Google Play, còn để xem toàn bộ trình tự từ tài khoản đến kênh phát hành công khai thì đọc bài viết về yêu cầu phát hành năm 2026.

      Cổng phát hành trước khi tải lên

      Mười một mục kiểm tra, mỗi mục có một bằng chứng đạt cụ thể. Hãy làm hết chúng trước khi tải lên thay vì sau khi Play báo có gì đó sai, và bạn biến một buổi gỡ lỗi không có điểm dừng thành một danh sách hữu hạn.

      Công cụ 12

      Cổng phát hành

      Đã qua 0 trên 11

      Chưa chứng minh được gì. Hãy bắt đầu từ chính bản dựng bạn định tải lên, chứ không phải bản cuối cùng bạn tình cờ còn mở.

      Tiến độ của bạn chỉ được lưu trong trình duyệt này. Không có gì được gửi đi đâu cả, và xóa dữ liệu trình duyệt sẽ xóa luôn tiến độ.

      Qua hết mười một cổng chứng minh sự căn chỉnh về mặt kỹ thuật so với các phép kiểm tra được dẫn trên trang này. Đó không phải lời hứa về việc được phê duyệt. Google Play vẫn có thể nêu ra vấn đề chính sách, nội dung hay chất lượng không liên quan trên cùng lần tải lên đó, và không danh sách kiểm tra nào ở đâu có thể nói thay cho những điều ấy.

      Chỗ này va chạm với thử nghiệm khép kín ra sao

      Không có gì trên trang này làm thay đổi yêu cầu tester của bạn, và cũng không có gì ở phía tester làm thay đổi bản dựng của bạn. Hai vấn đề chỉ va vào nhau ở một trục duy nhất: thời gian. Đợt thử nghiệm khép kín 14 ngày chạy trên một chiếc đồng hồ bạn không thể tạm dừng, còn việc truy tìm một thư viện native thì chạy trên chiếc đồng hồ không ai đoán được.

      Trình tự gây đau đớn thường diễn ra thế này. Một tài khoản nhà phát triển cá nhân bắt đầu thử nghiệm khép kín, khoảng thời gian 14 ngày duy trì tham gia liên tục bắt đầu chạy, rồi đâu đó giữa chừng một lần nâng cấp độ mục tiêu làm lộ ra cảnh báo 16 KB. Giờ nhà phát triển vừa dựng lại các phụ thuộc native vừa phải giữ cho nhóm tester quanh mình còn nguyên vẹn. Tải bản dựng mới lên kênh thử nghiệm thì không sao, và Google còn khuyến khích nhà phát triển tiếp tục cập nhật trong lúc thử nghiệm. Thứ làm hỏng cả đợt là phía tester im lặng.

      Đó chính là phần PrimeTestLab giữ cho ổn định. Chúng tôi cung cấp 12 tester thật trên thiết bị thật trải từ Android 7 đến 17, đã chọn tham gia và được giữ đủ 14 ngày, để việc dựng lại của bạn diễn ra trên một đợt thử nghiệm ổn định thay vì một đợt đang sụp đổ. Thử nghiệm bắt đầu trong 4-6 giờ, và chúng tôi đã làm việc này cho hơn 7.400 ứng dụng tại 120+ quốc gia với tỷ lệ thành công 99,9%.

      Tự tìm tester so với đợt thử nghiệm trọn gói

      Yêu cầu của Google Tự tìm Trọn gói
      Ít nhất 12 tester đã chọn tham gia Tìm, giải thích và đốc thúc người thật, rồi hy vọng không ai rời đi 12 tester được cung cấp và giữ suốt cả kỳ
      14 ngày liên tục Một tester rời đi giữa chừng là chuỗi 14 ngày đứt Nhóm được theo dõi để chuỗi ngày không bị đứt
      Thiết bị thật, người thật Máy ảo và tài khoản không hoạt động là lối tắt quen thuộc, cũng là lý do quen thuộc khiến đợt thử nghiệm hỏng Thiết bị thật từ Android 7 đến 17
      Thời gian đến lượt tham gia đầu tiên Vài ngày, tùy ai trả lời bạn Thử nghiệm bắt đầu trong 4-6 giờ
      Chi phí Thời gian của bạn, đúng vào tuần bạn đang bận dựng lại thư viện Từ $19.99, cộng 5% phí dịch vụ
      Dựng lại giữa đợt thử nghiệm Mỗi lần tải lên mới là thêm một vòng nhờ mọi người cập nhật Cứ đẩy bản dựng mới thoải mái; nhóm vẫn duy trì tham gia

      Nói thẳng về ranh giới: chúng tôi không dựng lại thư viện native cho bạn và bài viết này cũng không phải lời chào hàng cho việc đó. Phần việc 16 KB là của bạn, và toàn bộ nội dung phía trên được viết ra để phần việc đó ngắn nhất có thể. Thứ chúng tôi gỡ khỏi tay bạn là yêu cầu tester đang chạy song song, để hai vấn đề thôi giành nhau cùng hai tuần lễ.

      Mẹo về thứ tự

      Nếu bạn chưa bắt đầu thử nghiệm khép kín mà đã biết mình có thư viện native, hãy cho khoảng thời gian tester chạy trước rồi làm phần căn chỉnh bên trong khoảng đó. Google tính kỳ đủ điều kiện dựa trên việc tester duy trì tham gia liên tục chứ không dựa trên một bản dựng bị đóng băng, và Google khuyến khích nhà phát triển tiếp tục cập nhật trong lúc thử nghiệm, nên hai mốc thời gian có thể chồng lên nhau thay vì xếp nối tiếp. Trong lúc làm, hãy giữ nguyên kênh thử nghiệm và nhóm tester. Cách này thường tiết kiệm trọn một tuần.

      Câu hỏi thường gặp

      Google Play có đang từ chối ứng dụng không tương thích 16 KB ngay lúc này không?

      Tài liệu hiện hành của Google nói rằng kể từ ngày 1 tháng 2 năm 2027 bạn sẽ không phát hành được bản cập nhật nào nhắm tới Android 15 (cấp độ API 35) trở lên mà thiếu hỗ trợ 16 KB trên thiết bị 64 bit. Trước mốc đó, phần lớn nhà phát triển chỉ thấy một cảnh báo tương thích trong Play Console chứ không phải một rào chặn cứng. Hệ quả được ghi trong trang Google mà chúng tôi dẫn là bạn không phát hành được bản cập nhật chưa đạt yêu cầu, chứ không phải ứng dụng đã đăng bị gỡ tự động.

      Vì sao Google nói ngày 1 tháng 2 năm 2027 trong khi bài khác nói ngày 1 tháng 11 năm 2025?

      Ngày 1 tháng 11 năm 2025 là hạn chót Google công bố ban đầu và ngày 31 tháng 5 năm 2026 là một mốc gia hạn về sau, nay chỉ còn giá trị lịch sử. Tính đến ngày 5 tháng 8 năm 2026, trang Android Developers hiện hành và ảnh chụp cảnh báo Play Console hiện hành đều hiển thị ngày 1 tháng 2 năm 2027, nên nguồn gốc mới hơn là nguồn quyết định. Nhiều bài blog và câu trả lời AI vẫn dẫn mốc cũ vì chúng được viết trước khi thay đổi diễn ra.

      Tôi chưa từng viết C++. Vì sao ứng dụng của tôi lại bị ảnh hưởng?

      Một framework, SDK, plugin, game engine, cơ sở dữ liệu, thành phần media hay công cụ tạo ứng dụng đều có thể thêm tệp .so native vào, ngay cả khi mã nguồn của chính bạn là Dart, JavaScript, Python, Java hay Kotlin. Hướng dẫn của Google nói rõ là bao gồm cả ứng dụng dùng thư viện NDK một cách gián tiếp qua một phụ thuộc. Hãy mở tệp APK trong Android Studio bằng Build rồi Analyze APK; bất kỳ tệp .so nào nằm dưới lib đều có nghĩa là ứng dụng đã đóng gói có dùng mã native.

      Ứng dụng thuần Kotlin có cần thay đổi gì không?

      Theo Google, ứng dụng chỉ dùng Java hoặc Kotlin, kể cả toàn bộ thư viện và SDK bên trong, thì đã hỗ trợ thiết bị 16 KB. Google vẫn khuyên nên thử trong môi trường 16 KB để bắt các lỗi thoái lui ngoài dự tính. Hãy xác nhận rằng tệp APK phát hành thật sự không có thư mục lib trước khi gọi ứng dụng của bạn là thuần Kotlin, vì chỉ một phụ thuộc phân tích hay cơ sở dữ liệu cũng đủ thêm vào một thư mục như vậy.

      Phiên bản Flutter nào khắc phục cảnh báo kích thước trang 16 KB?

      Không nguồn chính thức nào xác lập một phiên bản Flutter duy nhất bảo đảm mọi ứng dụng và mọi plugin Flutter đều đạt yêu cầu. Ghi chú phát hành của Flutter 3.27 hẹp hơn vẻ ngoài của nó, chỉ bao phủ hỗ trợ 16 KB cho các mẫu plugin_ffi chứ không phải toàn bộ engine. Flutter 3.38 là cột mốc có tài liệu vững nhất: Flutter nói rõ việc nâng lên bản đó là bước chuẩn bị cho yêu cầu 16 KB của Play và đã đổi NDK mặc định sang r28. Cách an toàn nhất là chuyển sang bản Flutter ổn định hiện hành, cập nhật mọi plugin native, dựng lại bundle phát hành, rồi kiểm tra từng tệp .so sinh ra.

      Phiên bản React Native nào hỗ trợ trang 16 KB?

      React Native 0.77 là mốc chính thức rõ ràng. Thông báo phát hành của bản này nói rằng React Native đã sẵn sàng hỗ trợ đầy đủ kích thước trang 16 KB. Các module native của cộng đồng, mã C++ cục bộ và SDK bên thứ ba vẫn có thể mang theo tệp nhị phân không tương thích, nên hãy nâng cấp theo lộ trình di chuyển được hỗ trợ của React Native hoặc Expo rồi kiểm tra tệp APK sinh ra.

      Tôi cần phiên bản Unity nào để hỗ trợ kích thước trang 16 KB?

      Unity liệt kê 6000.1 trở lên, 6000.0.38f1 trở lên, 2022.3.56f1 trở lên, và 2021.3.48f1 trở lên theo diện LTS mở rộng dành cho khách hàng Enterprise hoặc Industry đủ điều kiện. Hãy cập nhật cả các plugin native, và nâng Burst lên 1.8.21 trở lên nếu Play Console nêu tên lib_burst_generated.so. Một phiên bản editor được hỗ trợ là cần nhưng chưa đủ, vì plugin bên thứ ba mang theo tệp nhị phân của riêng chúng.

      Làm sao tìm được đúng tệp .so đang gây lỗi?

      Mở tệp APK qua Build rồi Analyze APK trong Android Studio, mở rộng lib/arm64-v8a và lib/x86_64, rồi đọc cột Alignment, nơi hiển thị cảnh báo cho những tệp có vấn đề căn chỉnh. Muốn xác nhận bằng dòng lệnh, hãy chạy script check_elf_alignment.sh của Google trên tệp APK, hoặc kiểm tra một thư viện bằng llvm-objdump -p tep.so đưa qua grep LOAD. Mọi giá trị căn chỉnh LOAD dưới 2**14 đều cần xử lý.

      Vì sao APK của tôi đạt mà app bundle vẫn hỏng?

      Căn chỉnh ELF bên trong một thư viện và căn chỉnh ZIP bên trong sản phẩm đã đóng gói là hai phép kiểm tra khác nhau. Hãy chạy bundletool dump config --bundle=app.aab rồi grep tìm alignment: PAGE_ALIGNMENT_16K là đạt, còn PAGE_ALIGNMENT_4K nghĩa là các tệp APK sinh ra vẫn được yêu cầu ở mức 4 KB. Google cảnh báo cụ thể rằng Android Gradle Plugin 8.3 đến 8.5 có thể trông đúng ở máy bạn trong khi các tệp APK mà Play dựng từ bundle của bạn lại không được căn chỉnh ZIP đúng cách, nên hãy chuyển lên 8.5.1 trở lên.

      Chỉ cần nâng lên NDK r28 là đủ để khắc phục chưa?

      Chưa. NDK r28 trở lên biên dịch với căn chỉnh 16 KB theo mặc định, nhưng điều đó chỉ ảnh hưởng tới mã native được biên dịch trong lúc bản dựng của bạn chạy. Nó không thể viết lại một tệp .so đã biên dịch sẵn nằm bên trong gói AAR, plugin hay game engine của bên thứ ba. Mọi phụ thuộc native dựng sẵn đều phải tự được cập nhật, thay thế, hoặc dựng lại rồi nhập lại vào dự án.

      Làm sao thử nghiệm hỗ trợ 16 KB khi không có điện thoại phù hợp?

      Hãy cài một trong các image hệ thống Android Emulator 16 KB của Google qua SDK Manager, hoặc đặt một thiết bị được hỗ trợ qua Samsung Remote Test Lab. Dùng cách nào cũng vậy, trước hết hãy xác nhận môi trường bằng adb shell getconf PAGE_SIZE; kết quả phải là 16384 thì phép thử mới có ý nghĩa. Thành công trên máy ảo chứng minh hành vi lúc chạy chứ không chứng minh cách đóng gói, nên hãy tiếp tục kiểm tra cả bundle phát hành.

      Việc khắc phục 16 KB có đặt lại hay ảnh hưởng tới đợt thử nghiệm khép kín của tôi không?

      Google tính kỳ đủ điều kiện dựa trên ít nhất 12 người thử nghiệm duy trì tham gia liên tục trong 14 ngày, chứ không dựa trên một bản dựng bị đóng băng, và Google khuyến khích nhà phát triển tiếp tục cập nhật bản dựng trong lúc thử nghiệm. Google không công bố một cam kết dứt khoát bao trùm mọi tình huống thay thế bản dựng, nên cách an toàn nhất là giữ nhóm tester ổn định trong lúc bạn đẩy lên một bundle đã dựng lại và đạt chuẩn 16 KB giữa đợt thử nghiệm. PrimeTestLab cung cấp 12 tester thật trên thiết bị thật từ $19.99, cộng 5% phí dịch vụ, và giữ nhóm đó đủ 14 ngày.

      Tóm lại

      Tóm tắt

      Google Play yêu cầu ứng dụng nhắm tới Android 15 (cấp độ API 35) trở lên phải hỗ trợ kích thước trang bộ nhớ 16 KB trên thiết bị 64 bit, và kể từ ngày 1 tháng 2 năm 2027 các bản cập nhật chưa đạt yêu cầu sẽ không phát hành được. Ngày 1 tháng 11 năm 2025ngày 31 tháng 5 năm 2026 là những mốc đã chết nhưng vẫn xếp hạng cao. Ứng dụng thuần Java hoặc Kotlin thì vốn đã đạt yêu cầu. Còn lại đều làm đúng ba bước như nhau: gọi tên tệp .so bị lỗi, cập nhật gói sở hữu nó, rồi chứng minh sản phẩm bằng hai phép kiểm tra độc lập, đó là mọi phân đoạn LOAD của ELF phải ở 2**14 trở lên, và bundle phải báo PAGE_ALIGNMENT_16K. AGP 8.5.1+ cùng NDK r28+ là bộ công cụ mặc định an toàn nhất, và không cái nào sửa được tệp nhị phân do người khác biên dịch. Nếu chuyện này rơi vào giữa đợt thử nghiệm khép kín, phần tester chính là phần bạn có thể giao cho người khác. Xem bảng giá →

      Điều gì trên trang này sẽ cũ trước tiên

      • Mốc ngày 1 tháng 2 năm 2027. Google đã dời mốc thời gian này hơn một lần. Hãy kiểm tra dấu "Last updated" ở cuối trang hướng dẫn kích thước trang trước khi bạn lên kế hoạch phát hành quanh mốc đó.
      • Các dòng chữ trong Play Console. Câu chữ và điều hướng trong Console thay đổi độc lập với các trang chính sách, nên tiêu đề bạn nhìn thấy có thể khác với những gì được tái hiện ở đây.
      • Các mốc phiên bản của framework. Flutter ra bản ổn định rất thường xuyên, chính sách hỗ trợ của React Native luôn thay đổi, và điều kiện hưởng Unity LTS cũng đổi theo. Hãy đối chiếu với ghi chú phát hành hiện tại thay vì một con số phiên bản in trong bài viết.
      • Chỉ mục thư viện được báo cáo. Bất kỳ gói nào cũng có thể thêm, thay thế hoặc làm thoái lui một tệp nhị phân native ở bất kỳ bản phát hành nào. Luôn kiểm tra sản phẩm trong bundle của chính bạn.
      • Tên các image trình mô phỏng. Image mang nhãn thử nghiệm có thể được đổi tên hoặc nâng cấp, nên chuỗi ký tự chính xác trong SDK Manager có thể không khớp.

      Đã đối chiếu với tài liệu của Google vào ngày 9 tháng 8 năm 2026. Được rà soát hằng tháng cho tới ít nhất một tháng sau khi quy định có hiệu lực.

      Kefayatullah Khadem - Kỹ sư phần mềm và chuyên gia phát hành trên Google Play

      Tác giả

      Kefayatullah Khadem

      Kỹ sư phần mềm và chuyên gia phát hành trên Google Play

      Kefayatullah Khadem là kỹ sư phần mềm với hơn tám năm kinh nghiệm xây dựng các ứng dụng quy mô lớn. Tại PrimeTestLab, anh giúp các nhà phát triển vượt qua yêu cầu thử nghiệm khép kín của Google Play và những nút thắt phát hành khiến phần lớn mọi người mắc kẹt. Đến nay anh đã đồng hành cùng hơn 7.400 ứng dụng Android đạt quyền truy cập vào kênh phát hành công khai, tại 120+ quốc gia, với tỷ lệ thành công 99,9%. Anh cũng viết về chính sách của Google Play, các yêu cầu về bản dựng và hành trình thử nghiệm khép kín.

      7.400+ Ứng dụng đã thử nghiệm
      99,9% Tỷ lệ thành công
      120+ Quốc gia
      4.9/5 Đánh giá

      Tỷ lệ thành công 99,9%

      Bạn lo bản dựng. Tester để chúng tôi.

      Bạn dựng lại các thư viện native. Chúng tôi cung cấp 12 tester thật duy trì tham gia đủ 14 ngày trong lúc bạn làm việc đó.

      Chỉ từ $19.99, cộng 5% phí dịch vụ

      Bắt đầu thử nghiệm trong 4-6 giờ · 120+ quốc gia · Thử nghiệm lại miễn phí hoặc hoàn tiền toàn bộ

      Cùng hơn 7.400 nhà phát triển đã đưa ứng dụng lên Google Play với PrimeTestLab

      12 tester · $19.99 WhatsApp