gonnux.com



LIT-android-16kb-page-size-fix

2026-02-20

topic/android

요약

Android 15부터 16KB 메모리 페이지를 사용하는 기기가 등장했다. 앱에 포함된 native library(.so 파일)의 ELF LOAD 세그먼트가 16KB(0x4000)로 정렬되어 있지 않으면 Play Console에서 업로드가 거부된다. 자기가 직접 작성한 native 코드가 없어도, 의존하는 라이브러리가 .so를 포함하고 있으면 영향을 받는다.

원인 진단 방법

readelf -l 명령으로 .so 파일의 LOAD 세그먼트 alignment를 확인할 수 있다. 빌드 후 app/build/intermediates/merged_native_libs/ 디렉토리에서 실제 포함되는 .so 파일들을 확인한다.

readelf -l app/build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib/arm64-v8a/*.so | grep -A1 LOAD

0x1000이면 4KB 정렬(문제 있음), 0x4000이면 16KB 정렬(정상).

secure-qr 프로젝트에서의 해결

문제가 된 .so 파일 두 개:

파일명출처 라이브러리해결 방법
libbarhopper_v3.soML Kit barcode-scanning:17.3.0 (bundled)unbundled 버전(play-services-mlkit-barcode-scanning:18.3.1)으로 전환. 모델을 Play Services에서 다운로드하므로 APK에 .so 미포함
libimage_processing_util_jni.soCameraX camera-core:1.3.4CameraX 1.4.0으로 업데이트. 이 버전부터 16KB 정렬된 .so 제공

Bundled vs Unbundled ML Kit

ML Kit barcode scanning에는 두 가지 배포 방식이 있다:

  • Bundled (com.google.mlkit:barcode-scanning): ML 모델과 native lib을 APK에 포함. 설치 직후 오프라인 스캔 가능하지만, 16KB 미정렬 .so가 포함됨 (2026-02 기준 최신 17.3.0에서도 미수정)
  • Unbundled (com.google.android.gms:play-services-mlkit-barcode-scanning): Google Play Services를 통해 모델을 다운로드. APK에 native lib 미포함. 16KB 문제 회피. 단, Google Play Services가 없는 기기에서는 동작 안 함

두 방식 모두 동일한 com.google.mlkit.vision.barcode.* API를 사용하므로 코드 변경 없이 의존성만 교체하면 된다. 단, unbundled 사용 시 매니페스트에 아래 meta-data를 추가하여 앱 설치 시 모델을 자동 다운로드하도록 한다:

<meta-data
    android:name="com.google.mlkit.vision.DEPENDENCIES"
    android:value="barcode" />

나의 생각

16KB 이슈의 핵심은 "내 코드가 아닌 의존성의 native library"라는 점이다. 앱 개발자가 직접 수정할 수 없고, 라이브러리 제공자가 16KB 정렬된 빌드를 제공할 때까지 기다리거나 우회해야 한다. readelf -l로 어떤 .so가 문제인지 특정하고, Gradle의 빌드 산출물에서 확인하는 것이 디버깅의 핵심이다.

Links