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
A partir do Android 16, vamos ajustar a cota de tempo de execução de jobs regulares e acelerados com base nos seguintes fatores:
- Em qual bucket de espera do app o aplicativo está: no Android 16, os buckets de espera ativos vão começar a ser aplicados por uma cota de tempo de execução generosa.
- Se o job começar a execução enquanto o app estiver em um estado superior: no Android 16, os jobs iniciados enquanto o app estiver visível para o usuário e continuarem depois que o app ficar invisível vão obedecer à cota de tempo de execução do job.
- Se o job estiver sendo executado com um serviço em primeiro plano: no Android 16, os jobs que estiverem sendo executados simultaneamente com um serviço em primeiro plano vão obedecer à cota de tempo de execução do job. Se você estiver usando jobs para transferência de dados iniciada pelo usuário, considere usar jobs de transferência de dados iniciada pelo usuário.
Essa mudança afeta tarefas programadas usando o WorkManager, o JobScheduler e o
DownloadManager. Para depurar por que um job foi interrompido, recomendamos registrar por que ele foi interrompido chamando WorkInfo.getStopReason() (para jobs do JobScheduler, chame JobParameters.getStopReason()).
Para saber como o estado do app afeta os recursos que ele pode usar, consulte Limites de recursos de gerenciamento de energia. Para mais informações sobre práticas recomendadas de otimização da bateria, consulte as orientações sobre como otimizar o uso da bateria para APIs de programação de tarefas.
Também recomendamos usar a nova API
JobScheduler#getPendingJobReasonsHistory introduzida no
Android 16 para entender por que um job não foi executado.
Teste
Para testar o comportamento do app, é possível ativar a substituição de determinadas otimizações de cota de jobs enquanto o app estiver sendo executado em um dispositivo Android 16.
Para desativar a aplicação de "o estado principal vai obedecer à cota de tempo de execução do job", execute o seguinte comando adb:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS APP_PACKAGE_NAME
Para desativar a aplicação de "jobs em execução simultânea com um
serviço em primeiro plano vão obedecer à cota de tempo de execução do job", execute o seguinte
comando adb:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS APP_PACKAGE_NAME
Para testar determinado comportamento do bucket de espera do app, defina o bucket de espera do app
usando o seguinte comando adb:
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
Para entender em qual bucket de espera seu app está, use o seguinte comando adb:
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
JobInfo.Builder#setImportantWhileForeground(boolean) 方法用于在调度应用位于前台或暂时豁免于后台限制时指示作业的优先级。
自 Android 12(API 级别 31)起,此方法已废弃。从 Android 16 开始,它不再有效,系统会忽略调用此方法。
此功能移除也适用于 JobInfo#isImportantWhileForeground()。从 Android 16 开始,如果调用该方法,该方法会返回 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
O Android 16 descontinua os avisos de acessibilidade, caracterizados pelo uso de
announceForAccessibility ou o envio de
eventos de acessibilidade TYPE_ANNOUNCEMENT. Isso pode criar
experiências de usuário inconsistentes para usuários do TalkBack e do leitor de tela do Android.
As alternativas atendem melhor a uma gama mais ampla de necessidades dos usuários em várias
tecnologias assistivas do Android.
Exemplos de alternativas:
- Para mudanças significativas na interface, como mudanças de janela, use
Activity.setTitle(CharSequence)esetAccessibilityPaneTitle(java.lang.CharSequence). No Compose, useModifier.semantics { paneTitle = "paneTitle" }. - Para informar o usuário sobre mudanças na interface crítica, use
setAccessibilityLiveRegion(int). No Compose, useModifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive]}. Elas devem ser usadas com moderação, porque podem gerar avisos sempre que uma visualização é atualizada. - Para notificar os usuários sobre erros, envie um
AccessibilityEventdo tipoAccessibilityEvent#CONTENT_CHANGE_TYPE_ERRORe definaAccessibilityNodeInfo#setError(CharSequence)ou useTextView#setError(CharSequence).
A documentação de referência da API announceForAccessibility, que foi descontinuada, inclui mais detalhes sobre as alternativas sugeridas.
Suporte à navegação com três botões
Android 16 为已正确迁移到预测性返回的应用的三按钮导航栏引入了预测性返回支持。长按返回按钮会启动预测性返回动画,让您预览返回滑动手势会打开的界面。
此行为适用于系统中支持预测性返回动画的所有区域,包括系统动画(返回主屏幕、跨任务和跨 activity)。
Ícones temáticos automáticos de apps
A partir do Android 16 QPR 2, o Android aplica temas automaticamente aos ícones de apps para criar uma experiência coesa na tela inicial. Isso acontece se um app não fornecer um ícone temático próprio. Os apps podem controlar o design do ícone temático incluindo uma camada monocromática no ícone adaptável e conferindo uma prévia da aparência do ícone no 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
Um proprietário de dispositivo virtual é um app confiável ou privilegiado que cria e gerencia um dispositivo virtual. Os proprietários de dispositivos virtuais executam apps em um dispositivo virtual e os projetam na tela de um dispositivo remoto, como um computador pessoal, um dispositivo de realidade virtual ou um sistema de infoentretenimento automotivo. O proprietário do dispositivo virtual está em um dispositivo local, como um smartphone.
Substituições por app
Em dispositivos com o Android 16 (nível 36 da API), os proprietários de dispositivos virtuais podem substituir as configurações de apps em dispositivos virtuais selecionados que eles gerenciam. Por exemplo, para melhorar o layout do app, um proprietário de dispositivo virtual pode ignorar as restrições de orientação, proporção e redimensionamento ao projetar apps em uma tela externa.
Mudanças importantes comuns
O comportamento do Android 16 pode afetar a interface do app em formatos de tela grande, como telas de carros ou Chromebooks, especialmente layouts projetados para telas pequenas na orientação retrato. Para saber como tornar seu app adaptável a todos os formatos de dispositivos, consulte Sobre layouts adaptáveis.
Referências
Streaming de apps complementares
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
Android 16 针对一般的 Intent 重定向攻击提供了默认安全性,并且只需要最低限度的兼容性和开发者更改。
我们引入了默认安全加固解决方案,以应对 Intent 重定向漏洞。在大多数情况下,正常使用 intent 的应用不会遇到任何兼容性问题;我们在整个开发过程中收集了指标,以监控哪些应用可能会出现中断。
Intent 重定向在 Android 中出现,当攻击者可以部分或完全 控制用于在存在漏洞的应用上下文中启动新组件的 intent 内容时,而受害应用会在 intent 的 extra 字段中启动不受信任的子级 intent。这可能会导致攻击者应用在受害应用的上下文中启动私有组件、触发特权操作或获取对敏感数据的 URI 访问权限,从而可能导致数据窃取和任意代码执行。
选择停用 intent 重定向处理
Android 16 引入了一个新 API,允许应用选择停用启动安全保护。在默认安全行为会干扰合法应用用例的特定情况下,这可能是必要的。
对于针对 Android 16(API 级别 36)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) }
Apps complementares não são mais notificados sobre tempos limite de descoberta
O Android 16 apresenta um novo comportamento durante o
fluxo de pareamento de dispositivos complementares para proteger a privacidade de localização
do usuário contra apps maliciosos. Todos os apps complementares em execução no Android 16 não são
mais notificados diretamente do tempo limite de descoberta usando
RESULT_DISCOVERY_TIMEOUT. Em vez disso, o usuário é
notificado sobre eventos de tempo limite com uma caixa de diálogo visual. Quando o usuário dispensa
a caixa de diálogo, o app é alertado sobre a falha de associação com
RESULT_USER_REJECTED.
A duração da pesquisa também foi estendida em relação aos 20 segundos originais, e a descoberta de dispositivos pode ser interrompida pelo usuário a qualquer momento durante a pesquisa. Se pelo menos um dispositivo for descoberto nos primeiros 20 segundos após o início da pesquisa, o CDM vai parar de procurar outros dispositivos.
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.