Android 16 플랫폼에는 앱에 영향을 줄 수 있는 동작 변경사항이 있습니다. targetSdkVersion
과 관계없이 Android 16에서 실행되는 모든 앱에 적용되는 동작 변경사항은 다음과 같습니다. 이러한 변경사항을 적절히 지원해야 하는 경우 앱을 테스트한 후 필요에 따라 수정해야 합니다.
또한 Android 16을 타겟팅하는 앱에만 영향을 주는 동작 변경사항 목록을 검토해야 합니다.
핵심 기능
Android 16에는 Android 시스템의 다양한 핵심 기능을 수정하거나 확장하는 다음과 같은 변경사항이 포함되어 있습니다.
JobScheduler 할당량 최적화
Starting in Android 16, we're adjusting regular and expedited job execution runtime quota based on the following factors:
- Which app standby bucket the application is in: in Android 16, active standby buckets will start being enforced by a generous runtime quota.
- If the job starts execution while the app is in a top state: in Android 16, Jobs started while the app is visible to the user and continues after the app becomes invisible, will adhere to the job runtime quota.
- If the job is executing while running a Foreground Service: in Android 16, jobs that are executing while concurrently with a foreground service will adhere to the job runtime quota. If you're leveraging jobs for user initiated data transfer, consider using user initiated data transfer jobs instead.
This change impacts tasks scheduled using WorkManager, JobScheduler, and
DownloadManager. To debug why a job was stopped, we recommend logging why your
job was stopped by calling WorkInfo.getStopReason()
(for
JobScheduler jobs, call JobParameters.getStopReason()
).
For more information on battery-optimal best practices, refer to guidance on optimize battery use for task scheduling APIs.
We also recommend leveraging the new
JobScheduler#getPendingJobReasonsHistory
API introduced in
Android 16 to understand why a job has not executed.
Testing
To test your app's behavior, you can enable override of certain job quota optimizations as long as the app is running on an Android 16 device.
To disable enforcement of "top state will adhere to job runtime quota", run the
following adb
command:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS APP_PACKAGE_NAME
To disable enforcement of "jobs that are executing while concurrently with a
foreground service will adhere to the job runtime quota", run the following
adb
command:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS APP_PACKAGE_NAME
To test certain app standby bucket behavior, you can set the app standby bucket
of your app using the following adb
command:
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
To understand the app standby bucket your app is in, you can get the app standby
bucket of your app using the following adb
command:
adb shell am get-standby-bucket APP_PACKAGE_NAME
중단된 빈 작업 중지 사유
An abandoned job occurs when the JobParameters
object associated with the job
has been garbage collected, but JobService#jobFinished(JobParameters,
boolean)
has not been called to signal job completion. This indicates that
the job may be running and being rescheduled without the app's awareness.
Apps that rely on JobScheduler, don't maintain a strong reference to the
JobParameters
object, and timeout will now be granted the new job stop reason
STOP_REASON_TIMEOUT_ABANDONED
, instead of STOP_REASON_TIMEOUT
.
If there are frequent occurrences of the new abandoned stop reason, the system will take mitigation steps to reduce job frequency.
Apps should use the new stop reason to detect and reduce abandoned jobs.
If you're using WorkManager, AsyncTask, or DownloadManager, you aren't impacted because these APIs manage the job lifecycle on your app's behalf.
JobInfo#setImportantWhileForeground를 완전히 지원 중단했습니다.
JobInfo.Builder#setImportantWhileForeground(boolean)
메서드는 예약 앱이 포그라운드에 있거나 일시적으로 백그라운드 제한사항에서 제외된 경우 작업의 중요도를 나타냅니다.
이 메서드는 Android 12 (API 수준 31)부터 지원 중단되었습니다. Android 16부터는 더 이상 효과적으로 작동하지 않으며 이 메서드를 호출해도 무시됩니다.
이 기능 삭제는 JobInfo#isImportantWhileForeground()
에도 적용됩니다. Android 16부터 메서드가 호출되면 메서드는 false
를 반환합니다.
순서가 지정된 브로드캐스트 우선순위 범위가 더 이상 전역이 아님
Android 앱은 broadcast receiver의 우선순위를 정의하여 수신기가 브로드캐스트를 수신하고 처리하는 순서를 제어할 수 있습니다. 매니페스트 선언 수신기의 경우 앱은 android:priority
속성을 사용하여 우선순위를 정의할 수 있고 컨텍스트 등록 수신기의 경우 앱은 IntentFilter#setPriority()
API를 사용하여 우선순위를 정의할 수 있습니다. 브로드캐스트가 전송되면 시스템은 우선순위 순으로(최상위부터 최하위 순으로) 수신기에 브로드캐스트를 전달합니다.
Android 16에서는 여러 프로세스에서 android:priority
속성 또는 IntentFilter#setPriority()
를 사용하는 브로드캐스트 전송 순서가 보장되지 않습니다. 브로드캐스트 우선순위는 모든 프로세스 전반이 아닌 동일한 애플리케이션 프로세스 내에서만 적용됩니다.
또한 브로드캐스트 우선순위는 (SYSTEM_LOW_PRIORITY
+ 1,
SYSTEM_HIGH_PRIORITY
- 1) 범위로 자동으로 제한됩니다. 시스템 구성요소만 SYSTEM_LOW_PRIORITY
, SYSTEM_HIGH_PRIORITY
를 브로드캐스트 우선순위로 설정할 수 있습니다.
앱이 다음 중 하나를 실행하는 경우 영향을 받을 수 있습니다.
- 애플리케이션이 동일한 브로드캐스트 인텐트로 여러 프로세스를 선언했으며 우선순위에 따라 이러한 인텐트를 특정 순서로 수신할 것으로 예상합니다.
- 애플리케이션 프로세스는 다른 프로세스와 상호작용하며 특정 순서로 브로드캐스트 인텐트를 수신하는 것에 관한 기대치를 갖습니다.
프로세스가 서로 조정해야 하는 경우 다른 조정 채널을 사용하여 통신해야 합니다.
ART 내부 변경사항
Android 16 includes the latest updates to the Android Runtime (ART) that improve the Android Runtime's (ART's) performance and provide support for additional Java features. Through Google Play System updates, these improvements are also available to over a billion devices running Android 12 (API level 31) and higher.
As these changes are released, libraries and app code that rely on internal structures of ART might not work correctly on devices running Android 16, along with earlier Android versions that update the ART module through Google Play system updates.
Relying on internal structures (such as non-SDK interfaces) can always lead to compatibility problems, but it's particularly important to avoid relying on code (or libraries containing code) that leverages internal ART structures, since ART changes aren't tied to the platform version the device is running on and they go out to over a billion devices through Google Play system updates.
All developers should check whether their app is impacted by testing their apps thoroughly on Android 16. In addition, check the known issues to see if your app depends on any libraries that we've identified that rely on internal ART structures. If you do have app code or library dependencies that are affected, seek public API alternatives whenever possible and request public APIs for new use cases by creating a feature request in our issue tracker.
16KB 페이지 크기 호환성 모드
Android 15 introduced support for 16 KB memory pages to optimize performance of the platform. Android 16 adds a compatibility mode, allowing some apps built for 4 KB memory pages to run on a device configured for 16 KB memory pages.
If Android detects that your app has 4 KB aligned memory pages, it
automatically uses compatibility mode and display a notification dialog to the
user. Setting the android:pageSizeCompat
property in the AndroidManifest.xml
to enable the backwards compatibility mode will prevent the display of the
dialog when your app launches. For best performance, reliability, and stability,
your app should still be 16 KB aligned. Check out
our recent blog post
on updating your apps to support 16 KB memory pages for more details.

사용자 환경 및 시스템 UI
Android 16에는 더 일관되고 직관적인 사용자 환경을 제공하기 위한 다음과 같은 변경사항이 포함되어 있습니다.
방해가 되는 접근성 안내 지원 중단
Android 16에서는 announceForAccessibility
사용 또는 TYPE_ANNOUNCEMENT
접근성 이벤트 전송으로 특징되는 접근성 공지사항을 지원 중단합니다. 이로 인해 TalkBack 및 Android의 스크린 리더 사용자에게 일관되지 않은 사용자 환경이 발생할 수 있으며, 대안은 다양한 Android의 보조 기술에서 더 광범위한 사용자 요구사항을 충족합니다.
대안의 예:
- 창 변경과 같은 중요한 UI 변경의 경우
Activity.setTitle(CharSequence)
및setAccessibilityPaneTitle(java.lang.CharSequence)
를 사용하세요. Compose에서Modifier.semantics { paneTitle = "paneTitle" }
를 사용합니다. - 중요한 UI 변경사항을 사용자에게 알리려면
setAccessibilityLiveRegion(int)
를 사용하세요. Compose에서는Modifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive]}
를 사용합니다 . 뷰가 업데이트될 때마다 공지사항이 생성될 수 있으므로 이러한 공지사항은 가급적 사용하지 않는 것이 좋습니다. - 사용자에게 오류를 알리려면
AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR
유형의AccessibilityEvent
를 전송하고AccessibilityNodeInfo#setError(CharSequence)
를 설정하거나TextView#setError(CharSequence)
를 사용하세요.
지원 중단된 announceForAccessibility
API의 참조 문서에는 추천 대안에 관한 자세한 내용이 포함되어 있습니다.
3버튼 탐색 지원
Android 16에서는 뒤로 탐색 예측으로 적절하게 이전한 앱의 3버튼 탐색에 뒤로 탐색 예측을 지원합니다. 뒤로 버튼을 길게 누르면 뒤로 탐색 예측 애니메이션이 시작되어 뒤로 스와이프하면 이동할 위치를 미리 볼 수 있습니다.
이 동작은 시스템 애니메이션 (홈으로 돌아가기, 교차 작업, 교차 활동)을 비롯하여 뒤로 탐색 예측 애니메이션을 지원하는 시스템의 모든 영역에 적용됩니다.
기기 폼 팩터
Android 16에는 가상 기기 소유자가 디스플레이에 프로젝션할 때 앱에 적용되는 다음과 같은 변경사항이 포함되어 있습니다.
가상 기기 소유자 재정의
A virtual device owner is a trusted or privileged app that creates and manages a virtual device. Virtual device owners run apps on a virtual device and then project the apps to the display of a remote device, such as a personal computer, virtual reality device, or car infotainment system. The virtual device owner is on a local device, such as a mobile phone.

Per-app overrides
On devices running Android 16, virtual device owners can override app settings on select virtual devices that the virtual device owners manage. For example, to improve app layout, a virtual device owner can ignore orientation, aspect ratio, and resizability restrictions when projecting apps onto an external display.
Common breaking changes
The Android 16 behavior might impact your app's UI on large screen form factors such as car displays or Chromebooks, especially layouts that were designed for small displays in portrait orientation. To learn how to make your app adaptive for all device form factors, see About adaptive layouts.
References
보안
Android 16에는 악성 앱으로부터 앱과 사용자를 보호하는 데 도움이 되도록 시스템 보안을 개선하는 변경사항이 포함되어 있습니다.
인텐트 리디렉션 공격에 대한 보안이 강화됨
Android 16은 최소한의 호환성 및 개발자 변경사항으로 일반적인 Intent
리디렉션 공격에 대한 기본 보안을 제공합니다.
Intent
리디렉션 악용에 기본적으로 보안 강화 솔루션이 도입됩니다. 대부분의 경우 인텐트를 사용하는 앱은 일반적으로 호환성 문제가 발생하지 않습니다. Google은 개발 프로세스 전반에서 측정항목을 수집하여 중단이 발생할 수 있는 앱을 모니터링했습니다.
Android의 인텐트 리디렉션은 공격자가 취약한 앱의 컨텍스트에서 새 구성요소를 실행하는 데 사용되는 인텐트의 콘텐츠를 부분적으로 또는 완전히 제어할 수 있는 반면 피해자 앱이 ('최상위') 인텐트의 Extras 필드에서 신뢰할 수 없는 하위 수준 인텐트를 실행하는 경우에 발생합니다. 이로 인해 공격자 앱이 피해자 앱의 컨텍스트에서 비공개 구성요소를 실행하거나 권한이 있는 작업을 트리거하거나 민감한 정보에 대한 URI 액세스 권한을 획득하여 데이터 도난 및 임의의 코드 실행으로 이어질 수 있습니다.
인텐트 리디렉션 처리 선택 해제
Android 16에서는 앱이 실행 보안 보호를 선택 해제할 수 있는 새로운 API를 도입합니다. 이는 기본 보안 동작이 합법적인 앱 사용 사례를 방해하는 특정 경우에 필요할 수 있습니다.
Android 16 SDK 이상을 기준으로 컴파일하는 애플리케이션의 경우
Intent 객체에서 removeLaunchSecurityProtection()
메서드를 직접 사용할 수 있습니다.
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
Android 15 (API 수준 35) 이하를 기준으로 컴파일하는 애플리케이션
권장하지는 않지만 리플렉션을 사용하여 removeLaunchSecurityProtection()
메서드에 액세스할 수 있습니다.
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent", Intent::class.java)
try {
val removeLaunchSecurityProtection = Intent::class.java.getDeclaredMethod("removeLaunchSecurityProtection")
removeLaunchSecurityProtection.invoke(iSublevel)
} catch (e: Exception) {
// Handle the exception, e.g., log it
} // Opt-out from the security hardening using reflection
iSublevel?.let { startActivity(it) }
연결
Android 16에서는 주변기기와의 연결을 개선하기 위해 블루투스 스택에 다음과 같은 변경사항이 포함되었습니다.
채권 손실 처리 개선
Android 16부터 원격 결합 손실이 감지될 때 보안 및 사용자 환경을 개선하기 위해 블루투스 스택이 업데이트되었습니다. 이전에는 시스템이 자동으로 결합을 삭제하고 새 페어링 프로세스를 시작하여 의도치 않은 재페어링이 발생할 수 있었습니다. 앱이 결합 해제 이벤트를 일관된 방식으로 처리하지 않는 경우가 많았습니다.
환경을 통합하기 위해 Android 16에서는 시스템에 대한 결합 손실 처리를 개선했습니다. 이전에 페어링된 블루투스 기기를 다시 연결할 때 인증할 수 없는 경우 시스템은 링크를 연결 해제하고 로컬 페어링 정보를 유지하며 사용자에게 페어링 손실에 관해 알리고 다시 페어링하도록 안내하는 시스템 대화상자를 표시합니다.