A plataforma Android 16 inclui mudanças de comportamento que podem afetar seu app.
As mudanças de comportamento a seguir se aplicam a todos os apps quando executados no Android 16,
independente de targetSdkVersion. Teste seu app e modifique-o conforme necessário para ficar compatível com essas mudanças, se necessário.
Consulte também a lista de mudanças de comportamento que afetam apenas os apps destinados ao Android 16.
Funcionalidade principal
O Android 16 (nível 36 da API) inclui as seguintes mudanças que modificam ou expandem vários recursos principais do sistema Android.
Otimizações de cota do 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 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 information about how your app's state affects the resources it can use, see Power management resource limits. 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
Motivo de interrupção de jobs vazios abandonados
Um job abandonado ocorre quando o objeto JobParameters associado ao job
é coletado, mas JobService#jobFinished(JobParameters,
boolean) não é chamado para sinalizar a conclusão do job. Isso indica que
o job pode estar sendo executado e reprogramado sem que o app saiba.
Os apps que dependem do JobScheduler não mantêm uma referência forte ao objeto
JobParameters, e o tempo limite agora será concedido ao novo motivo de interrupção de job
STOP_REASON_TIMEOUT_ABANDONED, em vez de STOP_REASON_TIMEOUT.
Se houver ocorrências frequentes do novo motivo de interrupção, o sistema vai tomar medidas de mitigação para reduzir a frequência do job.
Os apps precisam usar o novo motivo de interrupção para detectar e reduzir jobs abandonados.
Se você estiver usando o WorkManager, o AsyncTask ou o DownloadManager, não será afetado porque essas APIs gerenciam o ciclo de vida do job em nome do app.
Suspensão total de JobInfo#setImportantWhileForeground
O método JobInfo.Builder#setImportantWhileForeground(boolean)
indica a importância de um job enquanto o app de programação está em primeiro plano
ou quando é temporariamente isento de restrições em segundo plano.
Esse método foi descontinuado a partir do Android 12 (nível 31 da API). A partir do Android 16, ele não funciona mais de forma eficaz, e a chamada desse método será ignorada.
Essa remoção de funcionalidade também se aplica a
JobInfo#isImportantWhileForeground(). A partir do Android
16, se o método for chamado, ele retornará false.
O escopo de prioridade de transmissão ordenada não é mais global
Android 应用可以为广播接收器定义优先级,以控制接收器接收和处理广播的顺序。对于清单声明的接收器,应用可以使用 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 设置为广播优先级。
如果您的应用执行以下任一操作,可能会受到影响:
- 您的应用声明了具有相同广播 intent 的多个进程,并且希望根据优先级以特定顺序接收这些 intent。
- 您的应用进程与其他进程交互,并期望以特定顺序接收广播 intent。
如果进程需要相互协调,则应使用其他协调渠道进行通信。
Mudanças internas do ART
O Android 16 inclui as atualizações mais recentes do Android Runtime (ART), que melhoram a performance do Android Runtime (ART) e oferecem suporte a outros recursos Java. Com as atualizações do sistema do Google Play, essas melhorias também estão disponíveis para mais de um bilhão de dispositivos com o Android 12 (nível 31 da API) e versões mais recentes.
À medida que essas mudanças são lançadas, bibliotecas e códigos de apps que dependem de estruturas internas do ART podem não funcionar corretamente em dispositivos com o Android 16, além de versões anteriores do Android que atualizam o módulo ART por meio de atualizações do sistema do Google Play.
A dependência de estruturas internas (como interfaces não SDK) pode sempre levar a problemas de compatibilidade, mas é particularmente importante evitar depender de código (ou bibliotecas que contenham código) que aproveite estruturas internas do ART, já que as mudanças do ART não estão vinculadas à versão da plataforma em que o dispositivo está executando e são enviadas para mais de um bilhão de dispositivos por meio de atualizações do sistema do Google Play.
Todos os desenvolvedores precisam verificar se o app é afetado testando-o completamente no Android 16. Além disso, verifique os problemas conhecidos para verificar se o app depende de bibliotecas que identificamos como dependentes de estruturas internas do ART. Se você tiver dependências de biblioteca ou código de app que foram afetadas, procure alternativas de API pública sempre que possível e solicite APIs públicas para novos casos de uso criando uma solicitação de recurso no nosso rastreador de problemas.
Modo de compatibilidade com tamanho de página de 16 KB
O Android 15 introduziu o suporte a páginas de memória de 16 KB para otimizar o desempenho da plataforma. O Android 16 adiciona um modo de compatibilidade, permitindo que alguns apps criados para páginas de memória de 4 KB sejam executados em um dispositivo configurado para páginas de memória de 16 KB.
Quando o app está em execução em um dispositivo com o Android 16 ou mais recente, se o Android
detectar que o app tem páginas de memória alinhadas de 4 KB, ele vai usar automaticamente
o modo de compatibilidade e mostrar uma caixa de diálogo de notificação para o usuário. Definir a
propriedade android:pageSizeCompat no AndroidManifest.xml para ativar o
modo de compatibilidade com versões anteriores vai impedir a exibição da caixa de diálogo quando o
app for iniciado. Para usar a propriedade android:pageSizeCompat, compile o app
usando o SDK do Android 16.
Para ter o melhor desempenho, confiabilidade e estabilidade, o app ainda precisa ter 16 KB alinhados. Confira nossa postagem recente do blog sobre como atualizar seus apps para oferecer suporte a páginas de memória de 16 KB para mais detalhes.
Experiência do usuário e interface do sistema
O Android 16 (nível 36 da API) inclui as seguintes mudanças que têm como objetivo criar uma experiência do usuário mais consistente e intuitiva.
Suspensão de anúncios de acessibilidade disruptivos
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 的参考文档中包含有关建议替代方案的更多详细信息。
Suporte à navegação com três botões
Android 16 为已正确迁移到预测性返回的应用的三按钮导航栏引入了预测性返回支持。长按返回按钮会启动预测性返回动画,让您预览返回滑动手势会打开的界面。
此行为适用于系统中支持预测性返回动画的所有区域,包括系统动画(返回主屏幕、跨任务和跨 activity)。
Ícones temáticos automáticos de apps
从 Android 16 QPR 2 开始,Android 会自动将主题应用于应用图标,以打造一致的主屏幕体验。如果应用未提供自己的带主题的应用图标,就会发生这种情况。应用可以通过在自适应图标中添加单色图层来控制主题化应用图标的设计,并在 Android Studio 中预览应用图标的外观。
Formatos de dispositivos
O Android 16 (nível 36 da API) inclui as seguintes mudanças para apps quando projetados em telas por proprietários de dispositivos virtuais.
Substituições do proprietário do dispositivo virtual
虚拟设备所有者是创建和管理虚拟设备的可信应用或特权应用。虚拟设备所有者在虚拟设备上运行应用,然后将应用投影到远程设备的显示屏上,例如个人电脑、虚拟现实设备或车载信息娱乐系统。虚拟设备所有者使用的是本地设备,例如手机。
按应用替换项
在搭载 Android 16(API 级别 36)的设备上,虚拟设备所有者可以替换其管理的特定虚拟设备上的应用设置。例如,为了改进应用布局,虚拟设备所有者在将应用投影到外部显示屏上时,可以忽略屏幕方向、宽高比和可调整大小性限制。
常见的重大更改
Android 16 的行为可能会影响应用在汽车显示屏或 Chromebook 等大屏幕设备规格上的界面,尤其是那些专为竖屏小显示屏设计的布局。如需了解如何让应用适应所有设备类型,请参阅关于自适应布局。
参考
Segurança
O Android 16 (nível 36 da API) inclui mudanças que promovem a segurança do sistema para ajudar a proteger apps e usuários contra apps maliciosos.
Segurança aprimorada contra ataques de redirecionamento de intents
O Android 16 oferece segurança padrão contra ataques gerais de redirecionamento de Intent, com compatibilidade mínima e mudanças necessárias para desenvolvedores.
Estamos introduzindo soluções de reforço da proteção de segurança padrão para exploits de redirecionamento de Intent. Na maioria dos casos, os apps que usam intents normalmente não apresentam problemas de compatibilidade. Coletamos métricas durante todo o processo de desenvolvimento para monitorar quais apps podem apresentar falhas.
O redirecionamento de intents no Android ocorre quando um invasor pode controlar total ou parcialmente o conteúdo de uma intent usada para iniciar um novo componente no contexto de um app vulnerável, enquanto o app da vítima inicia uma intent de subnível não confiável em um campo de extras de uma intent ("de nível superior"). Isso pode levar o app invasor a iniciar componentes particulares no contexto do app da vítima, acionando ações privilegiadas ou ganhando acesso de URI a dados sensíveis, o que pode levar ao roubo de dados e à execução de código arbitrário.
Desativar o processamento de redirecionamento de intents
O Android 16 apresenta uma nova API que permite que os apps desativem as proteções de segurança de inicialização. Isso pode ser necessário em casos específicos em que o comportamento de segurança padrão interfere em casos de uso legítimos do app.
Para aplicativos compilados com o SDK do Android 16 (nível 36 da API) ou mais recente
Você pode usar diretamente o método removeLaunchSecurityProtection() no objeto Intent.
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
Para aplicativos compilados com o Android 15 (nível 35 da API) ou versões anteriores
Embora não seja recomendado, você pode usar a reflexão para acessar o método 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) }
Apps complementares não são mais notificados sobre tempos limite de descoberta
Android 16 introduces a new behavior during
companion device pairing flow to protect the user's location
privacy from malicious apps. All companion apps running on Android 16 are no
longer directly notified of discovery timeout using
RESULT_DISCOVERY_TIMEOUT. Instead, the user is
notified of timeout events with a visual dialog. When the user dismisses
the dialog, the app is alerted of the association failure with
RESULT_USER_REJECTED.
The search duration has also been extended from the original 20 seconds, and the device discovery can be stopped by the user at any point during the search. If at least one device was discovered within the first 20 seconds of starting the search, the CDM stops searching for additional devices.
Conectividade
O Android 16 (nível 36 da API) inclui as seguintes mudanças na pilha do Bluetooth para melhorar a conectividade com dispositivos periféricos.
Tratamento aprimorado de perda de vínculo
A partir do Android 16, a pilha Bluetooth foi atualizada para melhorar a segurança e a experiência do usuário quando uma perda de vínculo remoto é detectada. Antes, o sistema retirava automaticamente a vinculação e iniciava um novo processo de pareamento, o que poderia levar a um novo pareamento não intencional. Em muitos casos, os apps não tratavam o evento de perda de vínculo de forma consistente.
Para unificar a experiência, o Android 16 melhorou o processamento de perda de vínculo para o sistema. Se um dispositivo Bluetooth pareado anteriormente não puder ser autenticado na reconexão, o sistema desconectará o link, manterá as informações de pareamento local e exibirá uma caixa de diálogo do sistema informando os usuários sobre a perda de pareamento e orientando-os a fazer o pareamento novamente.