런타임

런타임 모듈(com.android.runtime.release.apex)은 네이티브 및 관리형 Android 런타임을 위한 APEX 모듈입니다. 모듈에는 다음과 같은 구성요소가 포함됩니다.

  • ART
  • Bionic
  • Managed Core Library(Android 10의 새 구성요소)
  • ICU 라이브러리
  • libnativebridge
  • libnativehelper
  • libnativeloader

런타임 모듈은 Android 빌드 시에 생성되며 구성 프로젝트의 빌드 아티팩트를 포함합니다. 이 모듈은 마찬가지로 Android 10에서 새로 도입된 Conscrypt 모듈(com.android.conscrypt.apex) 및 시간대 데이터 모듈(com.android.tzdata.apex)과 모두 밀접하게 결합됩니다.

Android 런타임(ART) 변경사항

Android 10에서는 ART 빌드 시스템에서 런타임 모듈을 출시디버그(추가적인 진단 및 디버깅 도구 포함)라는 두 가지 변형으로 생성합니다. 출시 버전은 user 빌드에 설치되고 디버그 버전은 userdebugeng 빌드에 설치됩니다. 기기가 부팅되면 apexd/apex/com.android.runtime 아래에 런타임 모듈을 마운트합니다.

모듈에서 부팅 클래스 경로는 Managed Core Library와 같은 클래스, 다른 모듈의 클래스(예: Conscrypt 및 미디어) 및 시스템 파티션의 클래스(예: framework.jar) 사이에 분할됩니다. 모듈을 업데이트하면 dex2oat JIT가 모듈의 부팅 클래스를 컴파일합니다.

Android 10에는 다음과 같은 API 변경사항이 포함됩니다.

  • DEX 파일 지원을 위한 새로운 API가 시스템 코드(예: 스택 언와인더)와 ART 간의 안정적인 인터페이스를 제공합니다.
  • 새로운 API는 시스템에서 ART 전용 플랫폼 추상화 레이어(PAL)로 사용됩니다. 시스템 요소(libartpalette-system.so)는 ART가 의존한 시스템 기능을 노출하며 기기에 설치된 시스템 라이브러리를 로드하는 클라이언트 라이브러리(libartpalette.so)를 통해 액세스 가능합니다.

Android 10에서는 일부 ART 바이너리의 경로를 리팩터링하여 /system/bindalvikvm, dalvikvm32, dalvikvm64, dex2oat, dexdiag, dexdump, dexlist, dexoptanalyzer, oatdump, profman 바이너리를 런타임 모듈로 이동합니다. 호환성을 위해 리팩터링은 /system/bin에 심볼릭 링크를 포함합니다.

Bionic 변경사항

libctzcode는 런타임 모듈(/apex/com.android.runtime/etc/tz/) 및 시간대 데이터 모듈(/apex/com.android.tzdata/etc/tz/)에서 제공하는 시간대 데이터를 사용합니다. tzcode는 APEX 기반 시간대 업데이트(시간대 데이터 모듈에서 제공)보다 APK 기반 시간대 업데이트의 데이터에 우선순위를 두고 /system 데이터로 대체합니다.

libclibicuuc/libicui18n 대신 새 라이브러리(libandroidicu)를 사용합니다. 자세한 내용은 Managed Core Library를 참조하세요.

마지막으로 Bionic 공유 라이브러리와 동적 링커 경로가 심볼릭 링크로 전환됩니다(64비트 변형에도 적용됨). 누락 항목:

  • /system/lib/libc.so25.3.0 -> 25.4.0/apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so25.3.0 -> 25.4.0/apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so25.3.0 -> 25.4.0/apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker25.3.0 -> 25.4.0/apex/com.android.runtime/bin/linker

부팅 순서 변경사항

런타임 모듈을 지원하기 위해 Android 10은 부팅 시퀀스를 다음과 같이 업데이트합니다.

  1. init가 부트스트랩과 기본 마운트 네임스페이스를 준비합니다. tmpfs/apex에 마운트되고 마운트 지점의 전파 유형이 private로 설정됩니다.
  2. apexd는 기타 모든 프로세스에 앞서 부트스트랩 모드에서 시작되며 /system/apex에서 APEX 파일을 활성화하여 부트스트랩 마운트 네임스페이스에서 마운트합니다.
  3. 다른 사전 apexd 프로세스가 시작됩니다. 이러한 프로세스는 부트스트랩 마운트 네임스페이스에 있으며 시스템 APEX 파일의 라이브러리를 통해 제공됩니다.
  4. /data 마운트. init가 기본 마운트 네임스페이스로 전환되고 apexd를 데몬으로 시작합니다.
  5. apexd가 /data/apex/system/apex를 모두 스캔하고 이러한 디렉터리에서 가장 최근의 APEX 파일을 활성화합니다. 이 단계에서 활성화된 APEX 파일은 기본 네임스페이스에만 마운트되며 사전 apexd 프로세스에는 표시되지 않습니다.

Managed Core Library

Managed Core Library는 이전에 libcore로 알려져 있었던 하위 수준의 업데이트 가능한 관리(Android 런타임에서 실행된 dex) 코드의 모음입니다. Android 10에서는 Managed Core Library에 여러 Git 프로젝트와 platform/libcore/가 포함되며 새로운 용어는 코드 모음을 지칭합니다.

Managed Core Library는 런타임, 시간대 데이터 및 Conscrypt 모듈에서 제공하며 libjavacorelibandroidicu 등의 런타임 모듈에 있는 네이티브 라이브러리에 의존합니다. 수집된 코드는 libcore, apache-xml, boringssl, bouncycastle, conscrypt, expat, fdlibm, icu, okhttp, ziparchive, zlib등 여러 Git 프로젝트에서 가져온 것입니다. 라이브러리는 부팅 클래스 경로의 여러 .jar 파일(예: core-oj.jar, core-libart.jar, conscrypt.jar, okhttp.jar, bouncycastle.jar, apache-xml.jar) 간에 분할됩니다. 그러나 framework.jar 또는 ext.jar는 포함되지 않습니다.

구성요소 재구성

Android 10은 이전에 바이트 코드 조작을 사용하여 android.*com.android.* 아래에 구성된 여러 구성요소(bouncycastle/, conscrypt/, okhttp/)를 재구성합니다. 이러한 구성요소는 API 메타데이터에 자바 주석을 사용 설정할 수 있도록 소스 코드 변환을 통해 재구성됩니다.

Core Platform API

Core Platform API는 Android 프레임워크에서 사용 가능한 안정적인 코드 관리형 API를 제공하며, 모든 프레임워크 종속 항목이 명확하게 이해되었는지 확인하여 Managed Core Library를 업데이트할 수 있게 해줍니다. Core Platform API의 특징은 다음과 같습니다.

  • 공개 SDK API 외에도 종속 항목을 나타냅니다. API 콘텐츠는 libcore/mmodules/core_platform_api/를 참조하세요.
  • @libcore.api.CorePlatformApi를 사용하여 관리 코드에 명시적으로 주석을 답니다. libcore/ojluni/src/의 코드는 libcore/ojluni/annotations/mmodule/의 주석을, 다른 모든 프로젝트는 기본 소스 파일을 참조하세요.

빌드 시스템은 자바 소스 플랫폼 타겟을 빌드할 때(즉, .bp 파일에 "sdk_version:"이 없거나 .mk 파일에 "LOCAL_SDK_VERSION="이 없을 때) Core Platform API 사용이 기본으로 설정됩니다. 이러한 기본 설정은 Android 프레임워크 코드가 공개 API와 Core Platform API만 사용하도록 제한합니다(구현 클래스 없음). "core_current""current"와 같은 다른 sdk_version 값은 기존과 동일하게 작동합니다(공개 SDK API의 사용만 허용). 또한 빌드 시스템은 Core Platform API 노출 영역에 변경사항을 보고하고 소규모 예외 집합 외의 타겟이 Managed Core Library 내부 기능에 의존하지 않도록 합니다.

런타임 모듈은 Core Platform API가 적용되는 필드와 메서드에 액세스 검사를 실행합니다. 플랫폼 코드가 Core Platform API의 메서드에 액세스할 때 검사가 실행됩니다. 시스템 속성 persist.debug.dalvik.vm.core_platform_api_policy는 이러한 검사에 관한 정책을 제어합니다. 유효한 정책 값은 enabled, disabled, just-warn입니다. 디버그 및 eng 빌드의 경우 표준 정책은 just-warn이고 정책 위반이 감지되면 경고를 기록합니다. 사용자 빌드의 경우 기본 정책은 disabled이며 아무런 조치도 취해지지 않습니다. 또한 런타임 모듈은 네이티브 코드가 자바 네이티브 인터페이스(JNI)를 통해 필드와 메서드를 결정할 때 Core Platform API 검사를 실행합니다.

또한 Android 10에는 Android 프레임워크와 Managed Core Library 간의 API, 런타임 종속 항목 및 빌드 시간 종속 항목을 간소화하기 위한 여러 변경사항도 포함됩니다.

Android 10은 com.android.org.kxml2 아래에 org.kxml2 파서를 재구성합니다.

네이티브 라이브러리

Android 10은 Managed Core Library를 지원하는 네이티브 라이브러리를 리팩터링합니다. 이전에 플랫폼의 다른 부분과 공유되었던 동적으로 연결된 여러 라이브러리(예: libcrypto, libexpat, zlib)가 이제 복제되므로 런타임 링커 네임스페이스에 로드된 자체 사본이 런타임 모듈에 있습니다. 런타임 모듈에서 제공하는 동적으로 연결된 네이티브 라이브러리는 /apex/com.android.runtime/{lib,lib64}에 있습니다.

ICU 라이브러리

런타임 모듈에는 ICU 라이브러리(ICU4C 및 ICU4J)와 관련 데이터가 포함됩니다.

Android 10에는 ICU4C 함수의 하위 집합을 프레임워크 코드에 사용할 수 있는 새 동적 라이브러리 libandroidicu가 포함되어 있습니다. libandroidicu의 링커 기호는 ICU 전체 출시에 안정적입니다. 기호가 libicuuclibicui18n에 사용되는 _icu-version-number가 아닌 _android로 끝납니다. 그러나 앱 호환성을 위해 libicuuclibicui18n 기호를 계속 사용할 수 있습니다. 또한 앱 호환성을 위해 링커는 dlopen() 호출(즉, dlopen("/system/lib/libicuuc.so", ...)dlopen("/system/lib/libicui18n.so", ...))에서 절대 경로를 ICU 라이브러리로 리디렉션합니다. targetSdkVersion < 29인 앱의 경우 /apex/com.android.runtime/lib/에서 상응하는 라이브러리로 리디렉션합니다.

런타임 시 ICU 데이터 파일이 /apex/com.android.runtime/etc/icu/에 설치됩니다. 앱 호환성을 위해 Android 10에는 이전 ICU 데이터 파일 위치(/system/usr/icu/)로부터 /apex/com.android.runtime/etc/icu로의 심볼릭 링크가 포함됩니다.

Conscrypt 상호작용

Android 10에서는 논리적으로 Managed Core Library의 일부인 Conscrypt를 자체적으로 업데이트 가능한 APEX 모듈로 이동합니다. Conscrypt 및 런타임 모듈 사이에서 새로운 양방향 API 노출 영역은 공개 SDK API 외에 종속 항목을 나타냅니다(자세한 내용은 libcore/mmodules/intracoreapi/ 참고). API 요소에는 @libcore.api.IntraCoreApi를 사용하여 명시적으로 주석이 달립니다.

빌드 시스템은 Conscrypt 코드가 공개 API 및 인트라 코어 API로 제한되는지 확인합니다. Conscrypt에 관한 다른 Managed Core Library의 종속 항목은 리플렉션에 기반합니다. 빌드 시스템은 가능한 경우 이러한 종속 항목을 기록하고 API 노출 영역의 모든 변경사항을 보고합니다.

시간대 데이터 상호작용

Android 10에서 아키텍처 libcore, 런타임 libcore 및 ICU4J/ICU4C는 런타임 모듈(/apex/com.android.runtime/etc/tz/) 및 시간대 데이터 모듈(/apex/com.android.tzdata/etc/tz/)에서 제공하는 시간대 데이터를 사용합니다. 이러한 라이브러리에서는 다음을 실행합니다.

기타 변경사항

Android 10에서는 AsynchronousCloseMonitor API를 libnativehelper.so에서 libandroidio.so로 이동합니다. API는 AsynchronousCloseMonitor.h에서 노출됩니다.

libnativebridge 변경사항

Android 10은 libnativebridge 라이브러리를 런타임 모듈로 이동합니다. 이 라이브러리가 런타임 모듈의 일부인 libnativeloader 및 Bionic C 라이브러리와 밀접하게 결합되어 있기 때문입니다.

libnativehelper 변경사항

Android 10에서 런타임 모듈은 시스템 및 프레임워크 코드에서 libnativehelper를 사용할 수 있도록 하는 반면 런타임 모듈 외부의 코드는 libnativehelper의 스터브 API(C만)에 연결됩니다. libnativehelper 라이브러리에는 다음이 포함됩니다.

  • 캐시된 JNI 클래스, 메서드 및 필드의 축소된 집합
  • platform_include/jni_macros.h의 향상된 JNI 매크로
  • 네이티브 코드에서 java.nio.Buffer 클래스의 내부 기능에 액세스하는 새로운 JNI 도우미 메서드(libnativehelper/include/nativehelper/JNIHelp.h에서 jniGetNio로 시작하는 메서드 참조). 이러한 메서드는 프레임워크 코드에서 사용합니다.

libnativeloader 변경사항

Android 10에서 런타임 모듈에는 자바 클래스 로더의 링커 네임스페이스 생성을 담당하는 libnativeloader 라이브러리가 포함됩니다. 링커 네임스페이스는 관리형 코드로 작성된 Android 앱에 의해 로드된 네이티브 라이브러리에 적용됩니다. 라이브러리는 마찬가지로 모듈에 있는 Bionic 링커와 밀접하게 연결되어 있습니다.

libpac 변경사항

Android 10은 PacProcessor의 C API를 제공하는 libpac를 런타임 모듈로 이동합니다. libpac 라이브러리는 V8 자바스크립트 엔진 전체를 포함하며 PacProcessor(독립형 패키지 및 프로세스)를 제외하고는 사용하면 안 됩니다.

링커 구성 변경사항

Android 10에서는 런타임 모듈의 내부 동적 네이티브 라이브러리 종속 항목을 플랫폼과 기타 APEX 모듈로부터 구분하기 위해 링커 네임스페이스가 사용됩니다. runtime 링커 네임스페이스는 런타임 모듈 라이브러리에 설정되며 외부 종속 항목의 다른 네임스페이스와 적절하게 상호 연결됩니다.

링커 구성은 /vendor/system의 바이너리의 경우 /system/etc/ld.config.txt에 있고 런타임 모듈 자체(/apex/com.android.runtime/bin)에 있는 바이너리의 경우 /apex/com.android.runtime/etc/ld.config.txt에 있습니다.

SystemServer 및 프레임워크 변경사항

Android 10에서는 SystemServer가 런타임 모듈의 정보를 보고하기 위한 새로운 SystemServer를 호스팅합니다. 이 정보를 보려면 다음 ADB 명령어를 사용하세요.

adb shell dumpsys runtimeinfo

RuntimeService에 의해 관리되는 정보는 확장 가능합니다. 서비스 소스 코드는 frameworks/base/services/core/java/com/android/server/RuntimeService.java를 참조하세요. 예를 들어 클라이언트 코드는 libcore/luni/src/main/java/libcore/util/CoreLibraryDebug.java를 참조합니다.

또한 Android 10에서는 무선(OTA) 업데이트 프로세스를 업데이트하여 런타임 모듈의 dex2oat 및 기타 도구를 사용합니다.