Android 16 플랫폼에는 앱에 영향을 줄 수 있는 동작 변경사항이 있습니다. targetSdkVersion
과 관계없이 Android 16에서 실행되는 모든 앱에 적용되는 동작 변경사항은 다음과 같습니다. 이러한 변경사항을 적절히 지원해야 하는 경우 앱을 테스트한 후 필요에 따라 수정해야 합니다.
또한 Android 16을 타겟팅하는 앱에만 영향을 주는 동작 변경사항 목록을 검토해야 합니다.
핵심 기능
Android 16에는 Android 시스템의 다양한 핵심 기능을 수정하거나 확장하는 다음과 같은 변경사항이 포함되어 있습니다.
JobScheduler 할당량 최적화
Android 16부터 다음 요소를 기반으로 일반 및 신속한 작업 실행 런타임 할당량이 조정됩니다.
- 애플리케이션이 있는 앱 대기 버킷: Android 16에서는 활성 대기 버킷이 넉넉한 런타임 할당량으로 시행되기 시작합니다.
- 앱이 최상위 상태에 있는 동안 작업 실행이 시작되는 경우: Android 16에서는 앱이 사용자에게 표시되는 동안 시작된 작업이 앱이 표시되지 않게 된 후에도 계속되면 작업 런타임 할당량을 준수합니다.
- 포그라운드 서비스를 실행하는 동안 작업이 실행되는 경우: Android 16에서는 포그라운드 서비스와 동시에 실행되는 작업이 작업 런타임 할당량을 준수합니다. 사용자가 시작한 데이터 전송에 작업을 활용하는 경우 대신 사용자가 시작한 데이터 전송 작업을 사용하는 것이 좋습니다.
이 변경사항은 WorkManager, JobScheduler, DownloadManager를 사용하여 예약된 작업에 영향을 미칩니다. 작업이 중지된 이유를 디버그하려면 WorkInfo.getStopReason()
를 호출하여 작업이 중지된 이유를 로깅하는 것이 좋습니다 (JobScheduler 작업의 경우 JobParameters.getStopReason()
호출).
배터리 최적화 권장사항에 관한 자세한 내용은 작업 예약 API의 배터리 사용량 최적화 가이드를 참고하세요.
또한 Android 16에서 도입된 새로운 JobScheduler#getPendingJobReasonsHistory
API를 활용하여 작업이 실행되지 않은 이유를 파악하는 것이 좋습니다.
테스트
앱의 동작을 테스트하려면 앱이 Android 16 기기에서 실행되는 한 특정 작업 할당량 최적화 재정의를 사용 설정할 수 있습니다.
'최상위 상태가 작업 런타임 할당량을 준수합니다'의 시행을 사용 중지하려면 다음 adb
명령어를 실행합니다.
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS APP_PACKAGE_NAME
'포그라운드 서비스와 동시에 실행되는 작업은 작업 런타임 할당량을 준수합니다'의 시행을 사용 중지하려면 다음 adb
명령어를 실행합니다.
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS APP_PACKAGE_NAME
특정 앱 대기 버킷 동작을 테스트하려면 다음 adb
명령어를 사용하여 앱의 앱 대기 버킷을 설정하면 됩니다.
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
앱이 있는 앱 대기 버킷을 알아보려면 다음 adb
명령어를 사용하여 앱의 앱 대기 버킷을 가져오면 됩니다.
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 辅助技术的用户需求。
替代方案示例:
- 对于窗口更改等重大界面更改,请使用
Activity.setTitle(CharSequence)
和setAccessibilityPaneTitle(java.lang.CharSequence)
。在 Compose 中,使用Modifier.semantics { paneTitle = "paneTitle" }
- 如需向用户告知关键界面的更改,请使用
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에는 악성 앱으로부터 앱과 사용자를 보호하는 데 도움이 되도록 시스템 보안을 개선하는 변경사항이 포함되어 있습니다.
인텐트 리디렉션 공격에 대한 보안이 강화됨
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) }