Alterações de comportamento do Android 8.0

Com novos recursos e funcionalidades, o Android 8.0 (nível 26 da API) inclui uma variedade de mudanças de comportamento do sistema e da API. Este documento destaca algumas das principais mudanças que você precisa entender e considerar nos seus apps.

A maioria dessas mudanças afeta todos os aplicativos, independentemente da versão do Android que eles segmentam. Porém, muitas alterações afetam somente a segmentação de aplicativos Android 8.0 Para maximizar a clareza, esse é dividida em duas seções: Mudanças para todos os apps e Alterações na segmentação de apps Android 8.0

Mudanças para todos os apps

Essas mudanças de comportamento se aplicam a todos os apps quando executados na plataforma Android 8.0 (nível 26 da API), independentemente nível da API que eles segmentam. Todos os desenvolvedores devem revisar essas mudanças e modificar os aplicativos para oferecer suporte a elas adequadamente, quando for o caso.

Background execution limits

Como uma das mudanças que o Android 8.0 (nível 26 da API) introduz nos melhorar a duração da bateria, quando seu aplicativo entrar no armazenado em cache de estado, sem estado componentes, o sistema libera todos os wake locks retidos pelo aplicativo.

Além disso, para melhorar o desempenho do dispositivo, o sistema limita determinadas por apps que não estão em execução em primeiro plano. Especificamente:

  • Os aplicativos executados em segundo plano agora têm limites de liberdade possam acessar serviços em segundo plano.
  • Os apps não podem usar os manifestos para se registrar na maioria das transmissões implícitas ou seja, transmissões que não são direcionadas especificamente para o app.

por padrão, essas restrições só se aplicam a aplicativos destinados ao Android O. No entanto, os usuários podem ativar essas restrições para qualquer app na tela Configurações, mesmo que o aplicativo não seja direcionado a O.

O Android 8.0 (API de nível 26) também inclui as seguintes mudanças em métodos específicos:

  • O método startService() agora gera uma IllegalStateException se um app direcionados ao Android 8.0 tentam usar esse método em uma situação em que não é permitido criar serviços de segundo plano.
  • O novo método Context.startForegroundService() inicia uma serviço em primeiro plano. O sistema permite que apps para chamar Context.startForegroundService() mesmo quando o app estiver em segundo plano. No entanto, o app precisa chamar o método startForeground() desse serviço em cinco segundos após a criação do serviço.

Para mais informações, consulte Limites de execução em segundo plano.

Limites da localização em segundo plano no Android

Para economizar bateria, a experiência do usuário e a integridade do sistema, aplicativos em segundo plano recebem atualizações de localização com menos frequência quando usados em um dispositivo com Android 8.0. Essa mudança de comportamento afeta todos os apps que recebem atualizações de localização, incluindo o Google Play Services.

Essas mudanças afetam as seguintes APIs:

  • Fused Location Provider (FLP)
  • Geofencing
  • GNSS Measurements
  • Location Manager
  • Wi-Fi Manager

Para garantir que o aplicativo funcione como o esperado, faça o seguinte:

  • Revise a lógica do app e verifique se você está usando a localização mais recente. APIs de terceiros.
  • Testar se o app exibe o comportamento esperado para cada uso caso.
  • Considere usar o Fusada Provedor de localização (FLP, na sigla em inglês) ou fronteira geográfica virtual para lidar com os casos de uso que dependem a localização atual do usuário.

Para mais informações sobre essas mudanças, consulte Localização em segundo plano Limites.

Atalhos de apps

O Android 8.0 (API de nível 26) inclui as seguintes mudanças nos atalhos de apps:

  • O número de transmissão de com.android.launcher.action.INSTALL_SHORTCUT ainda mais afeta o aplicativo, porque agora ele é um ambiente privado, implícito transmissão. Em vez disso, crie um atalho usando o requestPinShortcut() da classe ShortcutManager.
  • O ACTION_CREATE_SHORTCUT agora pode criar atalhos de apps que você gerencia usando o ShortcutManager. Essa intent também pode criar atalhos legados da tela de início que não interagem com ShortcutManager: Antes, essa intent só podia Criar apenas atalhos legados na tela de início.
  • Atalhos criados usando requestPinShortcut() e atalhos criados em uma atividade que manipula a ACTION_CREATE_SHORTCUT agora são atalhos de apps completos. Por isso, eles podem ser atualizados pelos apps usando os métodos em ShortcutManager.
  • Os atalhos legados mantêm a funcionalidade das versões anteriores do Android, mas precisam ser convertidas manualmente em atalhos de apps.

Para saber mais sobre as mudanças nos atalhos de apps, consulte a Fixar atalhos e Widgets.

Localidades e internacionalização

O Android 7.0 (API de nível 24) introduziu o conceito de poder especificar uma localidade de categoria padrão, mas algumas APIs continuaram a usar o genérico Locale.getDefault() , sem argumentos, quando deveriam ter usado a localidade DISPLAY de categoria padrão. No Android 8.0 (API de nível 26), a os métodos a seguir agora usam Locale.getDefault(Category.DISPLAY). em vez de Locale.getDefault():

Locale.getDisplayScript(Locale) também volta para Locale.getDefault() quando o Valor displayScript especificado para Locale não está disponível.

Outras mudanças relacionadas a localidades e internacionalização são: da seguinte forma:

  • Chamar Currency.getDisplayName(null) gera uma NullPointerException, correspondendo ao comportamento documentado.
  • A análise do nome do fuso horário mudou. Antes, Dispositivos Android usaram o valor do relógio do sistema amostrado na inicialização tempo para armazenar em cache os nomes de fusos horários usados para analisar a data vezes. Como resultado, a análise poderia ser afetada negativamente se o sistema estava errado no momento da inicialização ou em casos mais raros.

    Em casos comuns, a lógica de análise usa a ICU e a valor atual do relógio do sistema ao analisar nomes de fusos horários. Isso alteração fornece resultados mais corretos, que podem ser diferentes dos anteriores Versões do Android quando o app usa classes como SimpleDateFormat:

  • O Android 8.0 (nível 26 da API) atualiza a ICU para a versão 58.

Janelas de alerta

Se um app usa a SYSTEM_ALERT_WINDOW permissão e usa um dos seguintes tipos de janela para tentar exibir janelas de alerta sobre outros apps e janelas do sistema:

...essas janelas sempre aparecem abaixo das janelas que usam o TYPE_APPLICATION_OVERLAY janela não é válido. Se um aplicativo for direcionado ao Android 8.0 (nível 26 da API), ele usará as TYPE_APPLICATION_OVERLAY para exibir janelas de alerta.

Para mais informações, consulte os Tipos de janela comuns para a seção de janelas de alerta nas alterações de comportamento de Aplicativos destinados ao Android 8.0.

Interação e navegação

Com o advento dos apps Android no ChromeOS e em outros formatos grandes, como tablets, estamos vendo um ressurgimento da navegação pelo teclado nos Apps Android. No Android 8.0 (API de nível 26), voltamos a lidar com o uso o teclado como um dispositivo de entrada de navegação, o que resulta em uma experiência previsível para navegação baseada em setas e guias.

Fizemos as seguintes alterações no foco do elemento comportamento:

  • Se você não definiu nenhuma cor do estado de foco para um Objeto View (em primeiro ou segundo plano) drawable), o framework define uma cor de destaque de foco padrão para o View. O destaque de foco é um drawable de ondulação com base no tema da atividade.

    Se você não quiser que um objeto View use esse padrão destacar quando receber foco, defina o android:defaultFocusHighlightEnabled para false no arquivo XML de layout que contém o View ou transmita false para setDefaultFocusHighlightEnabled() na lógica da interface do seu app.

  • Para testar como a entrada do teclado afeta o foco no elemento da interface, ative o Desenho > Opção para desenvolvedores Mostrar limites de layout. No Android 8.0, essa opção exibe um "X" ícone sobre o elemento que tem atualmente foco.

Além disso, todos os elementos da barra de ferramentas no Android 8.0 são automaticamente clusters de navegação por teclado, o que facilita a navegação dos usuários dentro e fora de cada barra de ferramentas como uma inteira.

Para saber mais sobre como melhorar o suporte à navegação pelo teclado no seu aplicativo, leia a documentação de Suporte Guia de navegação pelo teclado.

Preenchimento automático de formulários Web

Agora que o preenchimento automático do Android Framework oferece suporte integrado à funcionalidade de preenchimento automático, o os seguintes métodos relacionados a objetos WebView foram alterados para apps instalados em dispositivos com o Android 8.0 (nível 26 da API):

WebSettings
WebViewDatabase
  • Ligando Quantas pessoas recusaram: clearFormData() não tem mais efeito.
  • A Método hasFormData() agora retorna false. Antes, esse método retornava true quando o formulário continha dados.

Acessibilidade

O Android 8.0 (API de nível 26) inclui as seguintes mudanças de acessibilidade:

  • O framework de acessibilidade agora converte todos os gestos de dois toques em ACTION_CLICK ações. Essa mudança permite que o TalkBack se comporte de forma mais parecida serviços de acessibilidade.

    Se os objetos View do seu app usam toque personalizado verifique se eles ainda funcionam com o TalkBack. Talvez você basta registrar o gerenciador de cliques que seu View objetos usam. Se o TalkBack ainda não reconhecer os gestos realizados nesses View objetos, substituir performAccessibilityAction().

  • Os serviços de acessibilidade agora conhecem ClickableSpan de instâncias no objetos TextView.

Para saber mais sobre como tornar seu app mais acessível, consulte Acessibilidade.

Redes e conectividade HTTP(S)

O Android 8.0 (API de nível 26) inclui as seguintes mudanças de comportamento para rede e conectividade HTTP(S):

  • Solicitações OPTIONS sem corpo têm um Content-Length: 0 cabeçalho. Anteriormente, elas não tinham cabeçalho Content-Length.
  • HttpURLConnection normaliza URLs que contêm caminhos vazios anexando uma barra após o nome do host ou da autoridade com uma barra. Por exemplo, ela converte http://example.com em http://example.com/.
  • Um seletor de proxy personalizado definido por ProxySelector.setDefault(). segmenta apenas o endereço (esquema, host e porta) de um URL solicitado. Com isso, a seleção de proxy pode se basear apenas nesses valores. Um URL passado para um seletor de proxy personalizado não inclui o URL parâmetros de consulta ou fragmentos.
  • OS URIs não podem conter rótulos vazios.

    Antes, a plataforma oferecia uma solução alternativa para aceitar rótulos vazios em nomes de host, o que é um uso ilegal de URIs. Essa solução era para compatibilidade com versões libcore mais antigas. Desenvolvedores que usam a API incorretamente veria uma mensagem ADB: "URI example.com tem rótulos vazios em o nome do host. Isso está incorreto e não será aceito no futuro lançamentos". O Android 8.0 remove essa solução alternativa. o sistema retorna nulo para URIs malformados.

  • Implementação de HttpsURLConnection do Android 8.0 não executa substituto de versão do protocolo TLS/SSL não seguro.
  • A manipulação de conexões HTTP(S) de encapsulamento mudou da seguinte forma:
    • Ao encapsular uma conexão HTTPS por conexão, o sistema coloca corretamente o número da porta (:443) na linha do host ao enviar essas informações para um servidor intermediário. Antes, a porta número só ocorreu na linha CONNECT.
    • O sistema não envia mais o user agent e a autorização de proxy cabeçalhos de uma solicitação encapsulada para o servidor proxy.

      O sistema não envia mais um cabeçalho de autorização-proxy em um encapsulava Http(s)URLConnection ao proxy ao configurar a túnel do Cloud. Em vez disso, o sistema gera um cabeçalho proxy-autorização, e a envia para o proxy quando ele envia HTTP 407 em resposta à solicitação inicial.

      Da mesma forma, o sistema não copia mais o cabeçalho user agent da solicitação encapsulada para a solicitação de proxy que configura túnel do Cloud. Em vez disso, a biblioteca gera um cabeçalho user agent para esse solicitação.

  • O send(java.net.DatagramPacket) gera uma SocketException se o método connect() executado anteriormente falhou.
    • DatagramSocket.connect() define um pendingSocketException se houver um um erro interno. Antes do Android 8.0, uma função recv() subsequente chamada gerou uma SocketException, mesmo que uma chamada send() tivesse sido bem-sucedida. Para dar mais consistência, ambas as chamadas agora geram uma SocketException.
  • InetAddress.isReachable() tenta ICMP antes de voltar para o eco TCP protocolo.
    • Alguns hosts que bloqueiam a porta 7 (eco TCP), como google.com, podem se tornam acessíveis se aceitarem o protocolo ICMP de eco.
    • Para hosts realmente inacessíveis, essa alteração significa que o dobro da quantidade do tempo é gasto antes do retorno da chamada.

Bluetooth

O Android 8.0 (API de nível 26) faz as seguintes alterações no comprimento de os dados que o ScanRecord.getBytes() recupera:

  • O método getBytes() não faz suposições o número de bytes recebidos. Portanto, os apps não devem depender de nenhuma número mínimo ou máximo de bytes retornados. Em vez disso, eles devem avaliar o comprimento da matriz resultante.
  • Dispositivos compatíveis com Bluetooth 5 podem retornar comprimentos de dados que excedam o no máximo 60 bytes.
  • Se um dispositivo remoto não fornecer uma resposta de verificação, menos de 60 bytes também podem ser retornados.

Conectividade uniforme

O Android 8.0 (API de nível 26) traz várias melhorias nas configurações de Wi-Fi para facilitar a escolha a rede Wi-Fi que oferece a melhor experiência do usuário. Mudanças específicas incluem:

  • Melhorias de estabilidade e confiabilidade.
  • Uma IU de leitura mais intuitiva.
  • Um só menu consolidado de preferências de Wi-Fi.
  • Em dispositivos compatíveis, ativação automática do Wi-Fi quando uma rede salva de alta qualidade está por perto.

Segurança

O Android 8.0 inclui os seguintes recursos de segurança: muda:

  • A plataforma não oferece mais suporte a SSLv3.
  • Ao estabelecer uma conexão HTTPS com um servidor que implementa a negociação de versão do protocolo TLS, HttpsURLConnection não tenta mais a solução alternativa de voltar para versões anteriores do protocolo TLS e tentar novamente.
  • O Android 8.0 (nível 26 da API) aplica uma chave de computação filtrar por todos os apps. A lista de chamadas do sistema permitidas é restrita exposto por meio do biônico. Embora existam várias outras chamadas do sistema fornecidas para compatibilidade com versões anteriores, não recomendamos o uso deles.
  • Os objetos WebView do seu app agora são executados em multiprocesso modo O conteúdo da web é tratado em um processo separado e isolado que contém o processo do app para aumentar a segurança.
  • Não é mais possível presumir que os APKs estão em diretórios com nomes terminados em em -1 ou -2. Os apps devem usar sourceDir para acessar e não dependem diretamente do formato do diretório.
  • Para mais informações sobre melhorias de segurança relacionadas ao uso de bibliotecas, consulte Bibliotecas nativas.

Além disso, o Android 8.0 (API de nível 26) introduz as seguintes mudanças relacionadas à instalação apps desconhecidos de fontes desconhecidas:

Para mais detalhes sobre a instalação de apps desconhecidos, consulte a App desconhecido Permissões de instalação.

Para diretrizes adicionais sobre como tornar seu aplicativo mais seguro, consulte Segurança para desenvolvedores Android.

Privacidade

O Android 8.0 (API de nível 26) torna os seguintes controles de privacidade na plataforma.

  • Agora, a plataforma gerencia identificadores de forma diferente.
    • Para aplicativos que foram instalados antes de um OTA para uma versão do Android 8.0 (nível 26 da API) (API de nível 26), o valor do ANDROID_ID continua igual a menos que desinstalado e reinstalado após o OTA. Para preservar os valores em desinstalações após o OTA, os desenvolvedores podem associar os valores antigos e novos usando Backup de chave-valor.
    • Para aplicativos instalados em um dispositivo com o Android 8.0, o valor de ANDROID_ID agora está no escopo por chave de assinatura do app e por usuário. O valor de ANDROID_ID é único para cada combinação de chave de assinatura do app, usuário e dispositivo. Por isso, apps com chaves de assinatura diferentes são executados no mesmo dispositivo não vão mais ver o mesmo ID do Android (mesmo para o mesmo usuário).
    • O valor de ANDROID_ID não se altera na desinstalação ou reinstalação do pacote, contanto que o é a mesma (e o aplicativo não foi instalado antes de um OTA para um do Android 8.0).
    • O valor de ANDROID_ID não muda, mesmo que uma atualização do sistema faça com que a chave de assinatura do pacote mude.
    • Em dispositivos que enviam com o Google Play Services e o ID de publicidade, é preciso usar ID de publicidade. Um sistema padrão simples para gerar receita com apps, O ID de publicidade é único, reajustável pelo usuário e usado para publicidade. Ela é fornecida pelo Google Play Services.

      Outros fabricantes de dispositivos devem continuar para fornecer ANDROID_ID.

  • Consultar a propriedade do sistema net.hostname produz um valor nulo resultado.

Registro de exceções não capturadas

Se um app instalar um Thread.UncaughtExceptionHandler que não chamar o Thread.UncaughtExceptionHandler padrão, o sistema faz não encerrar o app quando ocorrer uma exceção não capturada. A partir de No Android 8.0 (API de nível 26), o sistema registra o stack trace da exceção situação; em versões anteriores da plataforma, o sistema não teria registrou o stack trace da exceção.

Recomendamos que o Thread.UncaughtExceptionHandler personalizado as implementações sempre chamam o gerenciador padrão, os apps que seguem essa recomendação não são afetados pelas a mudança no Android 8.0.

Mudança de assinatura findViewById()

Todas as instâncias do método findViewById() agora retornam <T extends View> T, em vez de View. Essa mudança tem as seguintes implicações:

  • Isso pode fazer com que o código tenha um tipo de retorno ambíguo, Por exemplo, se houver someMethod(View) e someMethod(TextView), que usa o resultado de uma chamada para findViewById()
  • Ao usar a linguagem de origem Java 8, isso exige uma transmissão explícita para View quando o tipo de retorno não tem restrições (por exemplo, assertNotNull(findViewById(...)).someViewMethod()).
  • Substituições de métodos findViewById() não finais (para exemplo, Activity.findViewById()) vão precisar do retorno tipo atualizado.

Mudança de estado de uso do provedor de contatos

Nas versões anteriores do Android, o componente do Provedor de contatos permite que os desenvolvedores recebam dados de uso de cada contato. Esses dados de uso expõe informações para cada endereço de e-mail e cada número de telefone associado com um contato, incluindo o número de vezes que ele foi contatado e a última vez em que o contato foi contatado. Apps que solicitam a READ_CONTACTS permissão podem ler esses dados.

Os apps ainda poderão ler esses dados se solicitarem READ_CONTACTS permissão. No Android 8.0 (nível 26 da API) e versões mais recentes, as consultas para dados de uso são retornadas aproximações em vez de valores exatos. O sistema Android mantém a valores exatos internamente, de modo que essa alteração não afete API de preenchimento automático.

Essa mudança de comportamento afeta os seguintes parâmetros de consulta:

Gerenciamento de coleta

AbstractCollection.removeAll() e AbstractCollection.retainAll() agora gera uma NullPointerException. antes, NullPointerException não foi gerada quando a coleta foi vazio. Essa mudança deixa o comportamento mais coerente com a documentação.

Android empresarial

O Android 8.0 (API de nível 26) altera a comportamento de algumas APIs e recursos para apps empresariais, incluindo as e controladores de política (DPCs). As mudanças incluem:

  • Novos comportamentos para ajudar os aplicativos a dar suporte a perfis de trabalho em dispositivos totalmente gerenciados.
  • Mudanças no tratamento de atualizações do sistema, verificação de apps e autenticação no aumentar a integridade do dispositivo e do sistema.
  • Melhorias na experiência do usuário para provisionamento, notificações, Tela "Recentes" e VPN sempre ativada.

Para conferir todas as mudanças empresariais no Android 8.0 (nível 26 da API) e saber como elas podem afetar seu aplicativo, leia Android nas empresas.

Apps destinados ao Android 8.0

Essas mudanças de comportamento se aplicam exclusivamente a apps direcionados Android 8.0 (nível 26 da API) ou mais recente Apps que podem ser compilados com o Android 8.0, ou definir targetSdkVersion como Android 8.0 ou versão posterior precisa modificar para oferecer suporte a esses comportamentos de forma adequada, quando aplicável.

Janelas de alerta

Apps que usam SYSTEM_ALERT_WINDOW a permissão não pode mais usar os seguintes tipos de janela para exibir alertas acima de outros apps e janelas do sistema:

Em vez disso, os apps precisam usar um novo tipo de janela chamado TYPE_APPLICATION_OVERLAY:

Ao usar o botão TYPE_APPLICATION_OVERLAY janela para exibir janelas de alerta para seu app, mantenha as seguintes características do novo tipo de janela em mente:

  • As janelas de alerta de um app sempre aparecem embaixo de janelas críticas do sistema, como como a barra de status e os IMEs.
  • O sistema pode mover ou redimensionar janelas que usam o TYPE_APPLICATION_OVERLAY tipo de janela para melhorar a apresentação na tela.
  • Ao abrir a aba de notificações, os usuários podem acessar as configurações para bloquear uma aplicativo de exibir janelas de alerta mostradas usando o TYPE_APPLICATION_OVERLAY tipo de janela.

Notificações de alteração de conteúdo

O Android 8.0 (API de nível 26) muda a forma ContentResolver.notifyChange() e registerContentObserver(Uri, boolean, ContentObserver) se comportam em apps destinados ao Android 8.0.

Essas APIs agora exigem que um objeto ContentProvider válido é definido para a autoridade em todos os URIs. Definir um ContentProvider válido com permissões relevantes vai ajudam a defender seu aplicativo contra alterações de conteúdo por aplicativos maliciosos e evitam que você do vazamento de dados potencialmente particulares para aplicativos maliciosos.

Foco de visualização

Os objetos View clicáveis agora também são focalizáveis por padrão. Se você quiser que um objeto View seja clicável, mas não focalizável, defina Atributo android:focusable para false no layout Arquivo XML que contém o View ou transmita false como setFocusable() na interface do app lógica.

Correspondência de user agent na detecção do navegador

O Android 8.0 (API de nível 26) e versões mais recentes incluem a string do identificador de build OPR. Algumas correspondências de padrões podem fazer com que a lógica de detecção do navegador identifique incorretamente um navegador que não seja Opera como o Opera. Um exemplo dessa correspondência de padrão pode ser:

if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}

Para evitar problemas decorrentes dessa identificação incorreta, use uma string diferente OPR como uma correspondência de padrão para o navegador Opera.

Segurança

As seguintes mudanças afetam a segurança no Android 8.0 (nível 26 da API):

  • Se a configuração de segurança de rede do seu app o que do suporte ao tráfego de texto não criptografado, Os objetos WebView não podem acessar sites por HTTP. Cada O objeto WebView precisa usar HTTPS.
  • A configuração do sistema Permitir fontes desconhecidas foi removida. na a permissão Instalar apps desconhecidos gerencia instalações de apps desconhecidos de fontes desconhecidas. Para saber mais sobre essa nova permissão, consulte a App desconhecido Permissões de instalação.

Para diretrizes adicionais sobre como tornar seu aplicativo mais seguro, consulte Segurança para desenvolvedores Android.

Detectabilidade e acesso a contas

No Android 8.0 (nível 26 da API), os apps não podem mais ter acesso a contas de usuário, a menos que o autenticador seja proprietário das contas ou usuário concede esse acesso. A Permissão para GET_ACCOUNTS não é mais suficiente. Para receber acesso a uma conta, os apps devem use AccountManager.newChooseAccountIntent() ou uma configuração de autenticação . Depois de ter acesso às contas, um app pode chamar AccountManager.getAccounts() para acessá-las.

O Android 8.0 foi descontinuado LOGIN_ACCOUNTS_CHANGED_ACTION: Aplicativos deve usar addOnAccountsUpdatedListener() para receber atualizações sobre as contas durante o tempo de execução.

Para informações sobre novas APIs e métodos adicionados para acesso à conta e detecção do dispositivo, consulte Acesso à conta e facilidade de descoberta na seção "Novas APIs" deste documento.

Privacidade

As mudanças abaixo afetam a privacidade no Android 8.0 (nível 26 da API).

  • As propriedades do sistema net.dns1, net.dns2, net.dns3 e net.dns4 não estão mais disponível, uma mudança que melhora a privacidade na plataforma.
  • Para obter informações de rede, como servidores DNS, aplicativos com ACCESS_NETWORK_STATE permissão podem registrar um NetworkRequest ou objeto NetworkCallback. Essas classes estão disponíveis no Android 5.0 (API de nível 21) e em versões posteriores.
  • Build.SERIAL está obsoleta. Os apps que precisam saber o número de série do hardware devem use o novo método Build.getSerial(), que requer o READ_PHONE_STATE permissão.
  • A API LauncherApps não permite mais o perfil de trabalho para acessar informações sobre o perfil principal. Quando um usuário está em um trabalho perfil, a API LauncherApps se comporta como se nenhum app estejam instalados em outros perfis dentro do mesmo grupo de perfis. Como antes, tentativas de acessar perfis não relacionados causam SecurityExceptions.

Permissões

Antes do Android 8.0 (nível 26 da API), se um app solicitava uma permissão durante a execução e a permissão foi concedida, o sistema também concedeu ao app as outras permissões que pertenciam ao mesmo grupo de permissões e que foram registrados no manifesto.

Para aplicativos destinados ao Android 8.0, esse comportamento foi corrigidas. O aplicativo recebe apenas as permissões que explicitamente solicitado. No entanto, depois que o usuário concede uma permissão ao aplicativo, todos solicitações subsequentes para permissões nesse grupo de permissões são concedidas automaticamente.

Por exemplo, suponha que um aplicativo liste READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE no manifesto. O app solicita READ_EXTERNAL_STORAGE e que o usuário concede. Se o aplicativo for direcionado ao nível de API 25 ou inferior, o sistema também concede WRITE_EXTERNAL_STORAGE ao mesmo momento, porque pertence ao mesmo grupo de permissões STORAGE e também é registrados no manifesto. Se o aplicativo for direcionado ao Android 8.0 (nível 26 da API), o sistema concederá somente READ_EXTERNAL_STORAGE naquele momento; No entanto, se o app solicitar WRITE_EXTERNAL_STORAGE depois, o sistema imediatamente concede esse privilégio sem notificar o usuário.

Mídia

  • O framework pode realizar redução automática de áudio sozinho. Nesse caso, quando outro aplicativo solicita o foco com AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, o aplicativo com foco reduz o volume, mas geralmente não recebe uma onAudioFocusChange() de retorno de chamada e não vai e perder a seleção de áudio. Novas APIs estão disponíveis para substituir esse comportamento por aplicativos que precisam pausar em vez de diminuir.
  • Quando o usuário atende a uma chamada, os streams de mídia ativos são silenciados durante o a chamada.
  • Todas as APIs relacionadas a áudio precisam usar AudioAttributes. em vez de tipos de stream de áudio para descrever o caso de uso de reprodução de áudio. Continue a usar tipos de stream de áudio somente para controles de volume. Outros usos dos tipos de stream ainda funcionam Por exemplo, o argumento streamType para a solicitação construtor AudioTrack), mas o sistema registra isso como um erro.
  • Ao usar um AudioTrack, se o aplicativo solicitar um buffer de áudio grande o suficiente, o o framework tentará usar a saída do buffer profundo se ela estiver disponível.
  • No Android 8.0 (API de nível 26), o processamento de eventos do botão de mídia é diferente:
    1. Como gerenciar os botões de mídia em uma atividade de interface não mudou: as atividades em primeiro plano ainda têm prioridade no processamento. eventos do botão de mídia.
    2. Se a atividade em primeiro plano não processar o evento do botão de mídia, o sistema vai rotear o evento ao app que reproduziu áudio localmente mais recentemente. O status ativo, as flags e a reprodução de uma sessão de mídia não são considerados ao determinar qual app recebe mídia eventos do botão.
    3. Se a sessão de mídia do app tiver sido lançada, o sistema envia o evento do botão de mídia para o MediaButtonReceiver, se houver.
    4. Para todos os demais casos de uso, o sistema descarta o evento de botão de mídia.

Bibliotecas nativas

Em apps destinados ao Android 8.0 (nível 26 da API), as bibliotecas nativas não carregam mais se contiverem algum segmento de carregamento que possa ser gravado e executável. Alguns apps podem parar de funcionar devido a essa mudança se tiverem bibliotecas nativas com segmentos de carregamento incorretos. Esta é uma medida de aumento de proteção.

Para obter mais informações, consulte Segmentos graváveis e executáveis.

As mudanças no vinculador são ligadas ao nível da API com que o aplicativo visa a trabalhar. Se houver é uma mudança do vinculador nível desejado da API, o app não vai conseguir carregar a biblioteca. Se você segmenta um nível de API inferior ao nível da API em que ocorre a mudança do vinculador o logcat exibe um aviso.

Gerenciamento de coleta

No Android 8.0 (nível 26 da API), Collections.sort() foi implementado em parte superior de List.sort(). O inverso era verdadeiro no Android 7.x (API de níveis 24 e 25): A implementação padrão de List.sort() chamado Collections.sort().

Essa mudança permite que o app Collections.sort() para aproveitar os List.sort() otimizados implementações, mas tem as seguintes restrições:

  • Implementações de List.sort() não pode chamar Collections.sort(), porque isso resultaria em um estouro de pilha devido à recursão infinita. Em vez disso, se você quiser que o comportamento padrão na implementação de List, evite substituir sort().

    Se uma classe mãe implementar sort() incorretamente, ela será geralmente pode substituir List.sort() com uma implementação criada com base List.toArray(), Arrays.sort() e ListIterator.set(). Exemplo:

    @Override
    public void sort(Comparator<? super E> c) {
      Object[] elements = toArray();
      Arrays.sort(elements, c);
      ListIterator<E> iterator = (ListIterator<Object>) listIterator();
      for (Object element : elements) {
        iterator.next();
        iterator.set((E) element);
      }
    }
    

    Na maioria dos casos, também é possível substituir List.sort() com um que delega para diferentes e implementações dependendo do nível da API. Exemplo:

    @Override
    public void sort(Comparator<? super E> comparator) {
      if (Build.VERSION.SDK_INT <= 25) {
        Collections.sort(this);
      } else {
        super.sort(comparator);
      }
    }
    

    Se você estiver fazendo a segunda opção apenas porque quer ter um sort() disponível em todos os níveis de API, dê um nome exclusivo a ela como sortCompat(), em vez de substituir sort():

  • Collections.sort() agora conta como uma modificação estrutural Liste implementações que chamam sort(). Por exemplo, nas versões plataforma anterior ao Android 8.0 (API de nível 26), iterando um ArrayList e chamar sort() nele no meio da iteração geraria uma ConcurrentModificationException. se a classificação foi feita chame List.sort(). Collections.sort() não gerou uma exceção.

    Essa mudança deixa o comportamento da plataforma mais consistente: abordagem agora resulta em uma ConcurrentModificationException.

Comportamento de carregamento de classe

O Android 8.0 (API de nível 26) faz verificações para garantir que os carregadores de classe não e quebrar as suposições do ambiente de execução ao carregar novas classes. Essas verificações são executada se a classe é referenciada em Java (do forName()). Bytecode Dalvik, ou JNI. A plataforma não intercepta chamadas diretas do Java para o loadClass(), nem verifica os resultados dessas chamadas. Esse comportamento não deve afetar o funcionamento de pessoas carregadores de classe.

A plataforma verifica se o descritor da classe retornado pelo carregador de classes corresponde ao descritor esperado. Se o descritor retornado não for correspondente, a plataforma gera um erro NoClassDefFoundError e armazena em para a exceção de uma mensagem detalhada indicando a discrepância.

A plataforma também analisa se os descritores das classes solicitadas são válidos. Isso a verificação captura chamadas JNI que carregam indiretamente classes como GetFieldID(), passando descritores inválidos para essas classes. Por exemplo, um campo com assinatura java/lang/String não foi encontrado porque essa assinatura é inválida. ele precisa ser Ljava/lang/String;.

Isso é diferente de uma chamada JNI para FindClass() em que java/lang/String é um nome totalmente qualificado válido.

O Android 8.0 (API de nível 26) não oferece suporte a vários carregadores de classes que tentam definir classes. usando o mesmo objeto DexFile. Uma tentativa de fazer isso faz com que o ambiente de execução do Android gere uma InternalError com a mensagem "Tentativa de registrar o arquivo dex <filename> com vários carregadores de classe".

A API DexFile foi descontinuada. Recomendamos o uso um dos carregadores de classe da plataforma, incluindo PathClassLoader ou BaseDexClassLoader.

Observação: você pode criar vários carregadores de classe que referenciam mesmo contêiner de arquivos APK ou JAR do sistema de arquivos. Fazer isso normalmente não causar sobrecarga de memória: se os arquivos DEX no contêiner forem armazenados em vez de compactado, a plataforma poderá executar uma operação mmap neles em vez de extraí-los diretamente. No entanto, se a plataforma precisar extrair o arquivo DEX do contêiner, referenciar um arquivo DEX dessa forma pode consumir muita memória.

No Android, todos os carregadores de classe são considerados passíveis de paralelismo. Quando várias linhas de execução competem para carregar a mesma classe com a mesma classe carregador, o primeiro encadeamento que concluir a operação vence, e o resultado é usado para as outras linhas. Esse comportamento ocorre independentemente de o carregador de classe retornou a mesma classe, retornou uma classe diferente ou acionou uma exceção. A plataforma ignora essas exceções silenciosamente.

Atenção : nas versões da plataforma anteriores ao Android 8.0 (API de nível 26), quebrar essas premissas pode levar à definição dos mesmos várias vezes, corrupção de heap devido à confusão de classes, e outros efeitos indesejáveis.