Além de novos recursos e funcionalidades, o Android 7.0 inclui uma variedade de mudanças de comportamento do sistema e da API. Este documento destaca algumas das principais mudanças que você deve entender e considerar nos seus apps.
Caso você já tenha um aplicativo para Android publicado, saiba que ele pode ser afetado pelas mudanças na plataforma.
Bateria e memória
O Android 7.0 inclui mudanças de comportamento do sistema com o objetivo de melhorar a vida útil da bateria dos dispositivos e reduzir o uso de RAM. Essas mudanças podem afetar o acesso do app aos recursos do sistema, bem como a forma como ele interage com outros apps por meio de determinadas intents implícitas.
Soneca
Introduzido no Android 6.0 (nível da API 23), o modo soneca aumenta a vida útil da bateria adiando atividades de CPU e rede quando um usuário deixa um dispositivo desconectado, parado e com a tela desativada. O Android 7.0 aprimora ainda mais o modo soneca aplicando um subconjunto de restrições de CPU e rede quando o dispositivo está desconectado e com a tela desativada, mas não necessariamente parado, como, por exemplo, quando o celular está no bolso do usuário.
Quando um dispositivo está sendo alimentado pela bateria e a tela ficou desligada por um determinado
tempo, o dispositivo entra no modo Soneca e aplica o primeiro subconjunto de restrições: ele
desliga o acesso à rede do app e adia trabalhos e sincronizações. Se o dispositivo ficar
parado por um determinado período após entrar no modo Soneca, o sistema vai aplicar
o restante das restrições desse modo a PowerManager.WakeLock
e
AlarmManager
alarmes, GPS e buscas por Wi-Fi. Independentemente
de as restrições de soneca serem aplicadas parcial ou totalmente, o sistema desperta o
dispositivo para breves janelas de manutenção, quando os aplicativos podem
acessar a rede e executar todos os trabalhos/sincronizações adiados.
A ativação da tela ou do dispositivo encerra o modo soneca e remove essas restrições de processamento. O comportamento adicional não afeta as recomendações e práticas recomendadas para a adaptação do app à versão anterior do modo soneca, introduzida no Android 6.0 (nível da API 23), como discutido em Otimização para soneca e App em espera. Você ainda precisa seguir essas recomendações, como usar o Firebase Cloud Messaging (FCM) para enviar e receber mensagens, e começar a planejar atualizações para acomodar o comportamento adicional do modo soneca.
Project Svelte: otimizações em segundo plano
O Android 7.0 remove três transmissões implícitas para ajudar a otimizar o uso de memória e o consumo de energia. Essa mudança é necessária porque transmissões implícitas iniciam frequentemente em segundo plano apps registrados para escutá-las. A remoção dessas transmissões pode beneficiar consideravelmente o desempenho do dispositivo e a experiência do usuário.
Os dispositivos móveis passam por mudanças frequentes na conectividade, como a alternância
entre Wi-Fi e dados móveis. No momento, os apps podem monitorar alterações de
conectividade registrando um receptor para a transmissão implícita CONNECTIVITY_ACTION
no
manifesto. Como muitos apps se registram para receber essa transmissão, uma única
troca de rede pode fazer com que todos despertem e processem a transmissão
ao mesmo tempo.
Da mesma forma, em versões anteriores do Android, os apps podiam se registrar para receber transmissões implícitas ACTION_NEW_PICTURE
e ACTION_NEW_VIDEO
de outros apps, como a
Câmera. Quando um usuário tira uma foto com o app Câmera, esses apps são ativados
para processar a transmissão.
Para aliviar esses problemas, o Android 7.0 aplica as seguintes otimizações:
- Os apps destinados ao Android 7.0 (API de nível 24) e versões mais recentes não receberão
transmissões
CONNECTIVITY_ACTION
se declararem o broadcast receiver no manifesto. Os apps ainda receberão transmissõesCONNECTIVITY_ACTION
se registrarem oBroadcastReceiver
noContext.registerReceiver()
e esse contexto ainda for válido. - O sistema não envia mais transmissões de
ACTION_NEW_PICTURE
ouACTION_NEW_VIDEO
. Essa otimização afeta todos os apps, não apenas aqueles para o Android 7.0.
Se o seu app usar qualquer uma dessas intents, remova as dependências
delas assim que possível para segmentar os dispositivos Android 7.0 corretamente.
O framework do Android oferece várias soluções para reduzir a necessidade
dessas transmissões implícitas. Por exemplo, a API JobScheduler
oferece um mecanismo robusto para programar
operações de rede quando condições especificadas, como conexão a uma
rede ilimitada, são atendidas. Você pode até usar JobScheduler
para reagir a mudanças nos provedores de conteúdo.
Para saber mais sobre as otimizações em segundo plano no Android 7.0 (nível 24 da API) e como adaptar seu app, consulte Otimizações em segundo plano.
Alterações nas permissões
O Android 7.0 inclui alterações nas permissões que podem afetar seu aplicativo.
Alterações nas permissões do sistema de arquivos
Para aprimorar a segurança de arquivos particulares, o diretório particular de
apps destinados ao Android 7.0 ou mais recente tem acesso restrito (0700
).
Essa configuração impede o vazamento de metadados de arquivos particulares, como tamanho
e existência. Essa alteração de permissão produz vários efeitos colaterais:
-
O proprietário não deve mais relaxar as permissões para arquivos privados,
e qualquer tentativa de fazer isso usando
MODE_WORLD_READABLE
e/ouMODE_WORLD_WRITEABLE
acionará umaSecurityException
.Observação:até agora, essa restrição não foi implementada com pleno vigor. Os apps ainda podem modificar permissões para o diretório privado usando APIs nativas ou a API
File
. No entanto, o relaxamento de permissões para o diretório privado é desencorajado. -
A passagem de URIs
file://
para fora do domínio do pacote pode deixar o receptor com um caminho inacessível. Sendo assim, tentativas de passar um URIfile://
acionam umaFileUriExposedException
. A maneira recomendada de compartilhar o conteúdo de um arquivo particular é usando oFileProvider
. -
O
DownloadManager
não consegue mais compartilhar arquivos armazenados de forma privada por nome de arquivo. Os aplicativos legados podem acabar em um caminho inacessível ao acessarCOLUMN_LOCAL_FILENAME
. Os apps destinados ao Android 7.0 ou versões mais recentes acionam umaSecurityException
quando tentam acessar oCOLUMN_LOCAL_FILENAME
. Aplicativos legados que definem o local de download como um local público usandoDownloadManager.Request.setDestinationInExternalFilesDir()
ouDownloadManager.Request.setDestinationInExternalPublicDir()
ainda conseguem acessar o caminho emCOLUMN_LOCAL_FILENAME
. No entanto, esse método é desencorajado. A maneira preferencial de acessar um arquivo exposto peloDownloadManager
é usandoContentResolver.openFileDescriptor()
.
Compartilhamento de arquivos entre aplicativos
Em apps destinados ao Android 7.0, o framework do Android aplica
a política de API StrictMode
, que proíbe a exposição de URIs file://
fora do app. Se uma intent com um URI de arquivo sair do app, ele vai falhar
com uma exceção FileUriExposedException
.
Para compartilhar arquivos entre aplicativos, você deve enviar um URI content://
e conceder uma permissão de acesso temporária ao URI. A forma mais fácil de conceder essa permissão é
usando a classe FileProvider
. Para mais informações sobre permissões e compartilhamento de arquivos, consulte Como compartilhar arquivos.
Melhorias na acessibilidade
O Android 7.0 inclui mudanças que visam aprimorar a facilidade de uso da plataforma para usuários com visão reduzida ou deficiente. Normalmente, essas mudanças não exigem alterações de código no app. No entanto, analise esse recurso e teste-o no app para avaliar possíveis impactos na experiência do usuário.
Zoom de tela
O Android 7.0 permite que os usuários definam o Tamanho da exibição, que aumenta ou reduz todos os elementos na tela, melhorando a acessibilidade do dispositivo para usuários com baixa visão. Os usuários não podem alterar o zoom da tela além da largura mínima de sw320dp, que é a largura do Nexus 4, um smartphone comum de tamanho médio.
Quando a densidade do dispositivo mudar, o sistema notificará os apps em execução das seguintes formas:
- Se um app é direcionado ao nível 23 da API ou anterior, o sistema automaticamente elimina todos os processos em segundo plano. Isso significa que, se um usuário sair desse app para abrir a tela Settings e mudar a configuração Display size, o sistema vai eliminar o app da mesma forma que faria em uma situação de pouca memória. Se o app tiver algum processo em primeiro plano, o sistema notificará esses processos sobre a mudança de configuração, conforme descrito em Processar mudanças durante a execução, como se a orientação do dispositivo tivesse mudado.
- Se um app for direcionado ao Android 7.0, todos os processos (em primeiro e segundo plano) serão notificados sobre a mudança de configuração, conforme descrito em Processar mudanças no momento da execução.
A maioria dos apps não precisa ser alterada para ser compatível com esse recurso, desde que os aplicativos sigam as práticas recomendadas do Android. Os itens específicos a serem verificados são:
- Teste o app em um dispositivo com largura de tela
sw320dp
e verifique se ele funciona adequadamente. - Quando a configuração do dispositivo mudar, atualize todas as informações
dependentes de densidade armazenadas no cache, como bitmaps no cache ou recursos carregados da
rede. Verifique se há mudanças de configuração quando o app é retomado do estado
pausado.
Observação:se você armazena em cache dados dependentes de configuração, recomendamos incluir metadados relevantes, como o tamanho de tela ou a densidade de pixels adequado para esses dados. Salvar esses metadados permite que você decida se será necessário atualizar os dados armazenados em cache após uma mudança de configuração.
- Evite especificar dimensões com unidades px, pois elas não são redimensionadas de acordo com
a densidade de tela. Em vez disso, especifique dimensões com unidades de pixel
independente de densidade (
dp
).
Configurações de visão no assistente de configuração
O Android 7.0 inclui Configurações de visão na tela de boas-vindas, onde os usuários podem definir as seguintes configurações de acessibilidade em um novo dispositivo: gesto de ampliação, tamanho da fonte, tamanho da tela e TalkBack. Essa mudança aumenta a visibilidade de bugs relacionados a configurações de tela diferentes. Para avaliar o impacto desse recurso, teste seus apps com essas configurações ativadas. As configurações podem ser encontradas em Configurações > Acessibilidade.
Aplicativos NDK vinculados a bibliotecas da plataforma
A partir do Android 7.0, o sistema impede que aplicativos vinculem-se dinamicamente a bibliotecas não NDK, o que pode fazer o aplicativo falhar. Essa mudança de comportamento visa criar uma experiência consistente no app para todas as atualizações da plataforma e diferentes dispositivos. Embora seu código possa não estar vinculado a bibliotecas privadas, é possível que uma biblioteca estática de terceiro no seu app esteja fazendo isso. Portanto, todos os desenvolvedores devem verificar se os apps não falham em dispositivos com o Android 7.0. Se o app usa código nativo, use apenas APIs públicas do NDK.
Seu app pode tentar acessar APIs privadas da plataforma de três maneiras:
- O aplicativo acessa bibliotecas privadas da plataforma diretamente. Atualize o app para incluir sua própria cópia dessas bibliotecas ou use as NDK APIs públicas.
- Seu app usa uma biblioteca de terceiros que acessa bibliotecas privadas da plataforma. Mesmo que você tenha certeza de que seu app não acessa bibliotecas privadas diretamente, é recomendável testá-lo quanto a esse cenário.
- O aplicativo referencia uma biblioteca não incluída no seu APK. Por
exemplo, isso pode acontecer se você tentar usar sua própria cópia do OpenSSL, mas
esquecer de inseri-lo no APK do app. O app pode funcionar normalmente em versões
da plataforma Android que incluem
libcrypto.so
. No entanto, o app pode falhar em versões mais recentes do Android que não incluem essa biblioteca (como o Android 6.0 e versões mais recentes). Para corrigir isso, agrupe todas as bibliotecas externas ao NDK ao APK.
Os apps não devem usar bibliotecas nativas não incluídas no NDK porque elas podem mudar ou ser removidas entre diferentes versões do Android. A mudança de OpenSSL para BoringSSL é um exemplo dessas alterações. Além disso, como não há requisitos de compatibilidade para bibliotecas de plataforma não incluídas no NDK, dispositivos diferentes podem oferecer níveis distintos de compatibilidade.
Para reduzir o impacto que essa restrição pode ter em apps
já lançados, um conjunto de bibliotecas que apresentam uso significativo, como
libandroid_runtime.so
, libcutils.so
,
libcrypto.so
e libssl.so
, estão temporariamente
acessíveis no Android 7.0 (nível 24 da API) para apps destinados ao nível 23 da API ou
versões anteriores. Se o app carregar uma dessas bibliotecas, o Logcat vai gerar um aviso
e uma notificação vai aparecer no dispositivo de destino para informar você. Se você receber esses avisos, atualize o app para incluir a própria cópia dessas bibliotecas ou usar apenas as APIs NDK públicas. Versões futuras da Plataforma
Android podem restringir totalmente o uso de bibliotecas privadas e causar uma
falha no app.
Todos os apps geram um erro em tempo de execução quando chamam uma API que não seja
pública nem temporariamente acessível. O resultado é que
System.loadLibrary
e dlopen(3)
retornam
NULL
e podem fazer o app falhar. Revise o código do app para remover o uso de APIs de plataforma privada e faça um teste completo dos apps usando um dispositivo ou emulador com o Android 7.0 (API de nível 24). Se você não tiver certeza se o app usa bibliotecas privadas, verifique o logcat para identificar o erro em tempo de execução.
A tabela a seguir descreve o comportamento que você deve esperar de um
app, dependendo do uso de bibliotecas nativas privadas e do nível da API
de destino (android:targetSdkVersion
).
Bibliotecas | Nível desejado da API | Acesso em tempo de execução via vinculador dinâmico | Comportamento do Android 7.0 (nível 24 da API) | Comportamento da plataforma Android futura |
---|---|---|---|---|
Pública do NDK | Alguma | Acessível | Funciona como o esperado | Funciona como o esperado |
Privado (bibliotecas privadas temporariamente acessíveis) | 23 ou inferior | Temporariamente acessível | Funciona como o esperado, mas você recebe um aviso do logcat. | Erro em tempo de execução |
Privado (bibliotecas privadas temporariamente acessíveis) | 24 ou superior | Restrito | Erro em tempo de execução | Erro em tempo de execução |
Privado (outro) | Alguma | Restrito | Erro em tempo de execução | Erro em tempo de execução |
Verificar se o aplicativo usa bibliotecas privadas
Para ajudar você a identificar problemas ao carregar bibliotecas privadas, o logcat pode gerar um aviso ou erro de tempo de execução. Por exemplo, se o app for direcionado ao nível 23 da API ou versões anteriores e tentar acessar uma biblioteca privada em um dispositivo com o Android 7.0, você poderá receber um aviso semelhante ao seguinte:
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" ("/system/lib/libandroid_runtime.so") needed or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120
Esses avisos do logcat mostram que biblioteca está tentando acessar uma API da plataforma privada, mas não farão o aplicativo falhar. No entanto, se o app for direcionado à API de nível 24 ou mais recente, o Logcat vai gerar o seguinte erro de execução, podendo fazer com que o app falhe:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" ("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so" is not accessible for the namespace "classloader-namespace" at java.lang.Runtime.loadLibrary0(Runtime.java:977) at java.lang.System.loadLibrary(System.java:1602)
Você também pode ver essas saídas do logcat se o app usar bibliotecas de terceiros
que se vinculam dinamicamente a APIs privadas da plataforma. A ferramenta readelf do
Android 7.0DK permite gerar uma lista de todas as bibliotecas compartilhadas vinculadas
dinamicamente de um determinado arquivo .so
executando o comando a seguir:
aarch64-linux-android-readelf -dW libMyLibrary.so
Atualizar o app
Confira algumas etapas que você pode seguir para corrigir esses tipos de erro e garantir que o app não falhe em atualizações futuras da plataforma:
- Se o app usar bibliotecas privadas da plataforma, atualize-o para incluir a própria cópia dessas bibliotecas ou use as NDK APIs públicas.
- Se o app usar uma biblioteca de terceiros que acesse símbolos privados, contate o autor da biblioteca para atualizá-la.
- Certifique-se de agrupar todas as bibliotecas externas ao NDK ao APK.
- Use funções JNI padrão em vez de
getJavaVM
egetJNIEnv
delibandroid_runtime.so
:AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or JavaVM::AttachCurrentThread from <jni.h>.
- Use
__system_property_get
em vez do símbolo particularproperty_get
delibcutils.so
. Para fazer isso, use__system_property_get
com o seguinte include:#include <sys/system_properties.h>
Observação:a disponibilidade e o conteúdo das propriedades do sistema não são testados pelo CTS. Uma melhor solução seria evitar usar essas propriedades.
- Use uma versão local do símbolo
SSL_ctrl
delibcrypto.so
. Por exemplo, vinculelibcyrpto.a
estaticamente no arquivo.so
ou inclua uma versão vinculada dinamicamente delibcrypto.so
de BoringSSL/OpenSSL e empacote-a no APK.
Android for Work
O Android 7.0 contém mudanças para apps voltados ao Android for Work, incluindo mudanças em instalação de certificados, redefinição de senha, gerenciamento de usuários secundários e acesso a identificadores de dispositivo. Se você estiver criando apps para ambientes do Android for Work, examine essas mudanças e modifique o app conforme necessário.
- Você precisa instalar um instalador de certificado delegado antes que o DPC possa
configurá-lo. Para apps de proprietários de perfis e dispositivos destinados ao Android 7.0 (nível 24 da API), instale o instalador de certificado delegado antes que o controlador de política de dispositivo (DPC, na sigla em inglês) chame
DevicePolicyManager.setCertInstallerPackage()
. Se o instalador não estiver instalado, o sistema gerará umaIllegalArgumentException
. - As restrições de redefinição de senha de administradores do dispositivo agora se aplicam também a
proprietários de perfil. Os administradores de dispositivo não podem mais usar
DevicePolicyManager.resetPassword()
para limpar senhas nem para alterar as que já estão definidas. Os administradores de dispositivo ainda poderão definir uma senha, mas apenas em dispositivos sem senha, PIN ou padrão. - Donos de dispositivo e perfil poderão gerenciar contas, mesmo se restrições forem
definidas. Os proprietários de dispositivos e de perfil podem chamar as APIs de gerenciamento de conta, mesmo que haja restrições de usuário do
DISALLOW_MODIFY_ACCOUNTS
em vigor. - Os donos de dispositivo podem gerenciar usuários secundários com maior facilidade. Quando um dispositivo está
sendo executado no modo de proprietário do dispositivo, a restrição
DISALLOW_ADD_USER
é definida automaticamente. Isso impede que os usuários criem usuários secundários não gerenciados. Além disso, os métodosCreateUser()
ecreateAndInitializeUser()
foram descontinuados e serão substituídos pelo novo métodoDevicePolicyManager.createAndManageUser()
. - Os proprietários de dispositivo podem acessar identificadores de dispositivo. O proprietário do dispositivo pode acessar o
endereço MAC Wi-Fi de um dispositivo usando
DevicePolicyManager.getWifiMacAddress()
. Se o Wi-Fi nunca tiver sido ativado no dispositivo, esse método retornará o valornull
. - A configuração modo de trabalho controla o acesso a aplicativos de trabalho. Quando o modo de trabalho está desativado, a tela de início do sistema mostra os aplicativos de trabalho em cinza para indicar que estão indisponíveis. Quando reativado, o modo de trabalho retorna ao comportamento normal.
- Ao instalar um arquivo PKCS #12 que contenha uma cadeia de certificados de cliente e
a chave privada correspondente na interface de configurações, o certificado de CA da
cadeia não será mais instalado no armazenamento de credenciais confiáveis. Isso não
afeta o resultado de
KeyChain.getCertificateChain()
quando os apps tentam recuperar a cadeia de certificados do cliente mais tarde. Se necessário, o certificado de CA precisa ser instalado no armazenamento de credenciais confiáveis pela IU de Settings, com um formato codificado DER em uma extensão de arquivo .crt ou .cer. - A partir do Android 7.0, o registro e o armazenamento de impressão digital são gerenciados por usuário. Se o cliente Device Policy (DPC) do proprietário do perfil for direcionado à API de nível 23 (ou anterior) em um dispositivo com Android 7.0 (API de nível 24), o usuário ainda poderá definir uma impressão digital no dispositivo, mas os aplicativos de trabalho não poderão acessá-la. Quando o DPC visar o nível 24 da API e versões mais recentes, o usuário poderá ativar a impressão digital especificamente para o perfil de trabalho acessando Configurações > Segurança > Segurança do perfil de trabalho.
- Um novo status de criptografia
ENCRYPTION_STATUS_ACTIVE_PER_USER
é retornado porDevicePolicyManager.getStorageEncryptionStatus()
para indicar que a criptografia está ativa e que a chave de criptografia está vinculada ao usuário. O novo status só será retornado se o DPC visar trabalhar com API de nível 24 e posteriores. Para apps que visam trabalhar com níveis de API mais antigos,ENCRYPTION_STATUS_ACTIVE
é retornado, mesmo que a chave de criptografia seja específica do usuário ou do perfil. - No Android 7.0, diversos métodos que normalmente afetariam todo o
dispositivo se comportariam de forma diferente se o dispositivo tivesse um perfil de trabalho instalado com um
desafio de trabalho separado. Em vez de afetar todo o dispositivo, esses
métodos se aplicam apenas ao perfil de trabalho. A lista completa desses métodos está na documentação de
DevicePolicyManager.getParentProfileInstance()
. Por exemplo,DevicePolicyManager.lockNow()
bloqueia apenas o perfil de trabalho, em vez de bloquear todo o dispositivo. Para cada um desses métodos, você pode receber o comportamento antigo chamando o método na instância pai doDevicePolicyManager
. Você pode acessar esse pai chamandoDevicePolicyManager.getParentProfileInstance()
. Por exemplo, se você chamar o métodolockNow()
da instância mãe, todo o dispositivo será bloqueado.
Retenção de anotações
O Android 7.0 resolve um problema em que a visibilidade das anotações foi ignorada. Esse problema ativou o ambiente de execução para acessar anotações que não deveria acessar. Dentre essas anotações, estão:
VISIBILITY_BUILD
: que só deveria estar visível em tempo de build.VISIBILITY_SYSTEM
: que deveria estar visível em tempo de execução, mas apenas para o sistema em questão.
Se o seu app se baseou neste comportamento, adicione uma política de retenção para anotações que seja disponibilizada
em tempo de execução. Para isso, use @Retention(RetentionPolicy.RUNTIME)
.
Mudanças na configuração padrão de TLS/SSL
O Android 7.0 faz as seguintes alterações na configuração padrão de TLS/SSL usada por apps para HTTPS e outros tipos de tráfego TLS/SSL:
- Os conjuntos de criptografia RC4 agora estão desativados.
- Os pacotes de criptografia CHACHA20-POLY1305 estão ativados.
A desativação do RC4 por padrão pode causar problemas na conectividade HTTPS ou TLS/SSL quando o servidor não negocia pacotes de criptografia modernos. A solução recomendada é aprimorar a configuração do servidor para que ele trabalhe com conjuntos e protocolos de criptografia mais seguros e modernos. O ideal seria ter TLSv1.2 e AES-GCM ativados e os conjuntos de criptografia Forward Secrecy (ECDHE) ativos e sendo os preferenciais.
Uma alternativa é modificar o app para usar um SSLSocketFactory
personalizado para se comunicar com o servidor. A fábrica precisa ser projetada para criar instâncias de SSLSocket
que tenham alguns dos conjuntos de criptografia exigidos pelo servidor ativados, além dos conjuntos de criptografia padrão.
Observação:essas mudanças não se aplicam a WebView
.
Apps destinados ao Android 7.0
Essas mudanças de comportamento se aplicam exclusivamente a apps destinados ao
Android 7.0 (nível 24 da API) ou mais recente. Os apps que são compilados para o Android 7.0
ou definem targetSdkVersion
para o Android 7.0 ou mais recente precisam ser modificados
para oferecer suporte a esses comportamentos de forma adequada, quando aplicável.
Mudanças de serialização
O Android 7.0 (nível 24 da API) corrigiu um bug no cálculo do serialVersionUID padrão, em que ele não correspondia à especificação.
Classes que implementam Serializable
e não especificam um campo serialVersionUID
explícito podem
apresentar uma mudança no serialVersionUID padrão, o que causaria uma exceção
ao tentar desserializar instâncias da classe que foram
serializadas em uma versão anterior ou serializadas por um app direcionado a uma versão
anterior. A mensagem de erro será semelhante a esta:
local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567
Para corrigir esses problemas, adicione um campo serialVersionUID
a
qualquer classe afetada com o valor de stream classdesc
serialVersionUID
da mensagem de erro, por exemplo, 1234
neste
caso. Essa mudança segue todas as recomendações de boas práticas para
escrever código de serialização e vai funcionar em todas as versões do Android.
O bug específico corrigido estava relacionado à presença de métodos de inicialização
estáticos, ou seja, <clinit>
. De acordo com a
especificação, a presença ou ausência de um método de inicialização estático na
classe vai afetar o serialVersionUID padrão calculado para essa classe.
Antes da correção do bug, o cálculo também verificava a superclasse em busca de um
inicializador estático, caso uma classe não tivesse um.
Para esclarecer, essa mudança não afeta apps destinados aos níveis 23 ou
anteriores da API, classes que têm um campo serialVersionUID
ou classes
que têm um método de inicialização estático.
Outros pontos importantes
- Quando um app é executado no Android 7.0, mas é direcionado a um nível de API mais baixo,
e o usuário muda o tamanho da tela, o processo do app é encerrado. O app
precisa ser capaz de processar corretamente esse cenário. Caso contrário, ele falhará
quando o usuário restaurá-lo em Recents.
Você deve testar o app para garantir que esse comportamento não ocorra. É possível fazer isso causando uma falha idêntica ao eliminar o app manualmente pelo DDMS.
Os apps destinados ao Android 7.0 (nível 24 da API) e versões mais recentes não são eliminados automaticamente em mudanças de densidade. No entanto, eles podem continuar respondendo mal a mudanças de configuração.
- Os apps no Android 7.0 precisam ser capazes de processar corretamente mudanças de configuração e não devem falhar em inicializações subsequentes. Você pode verificar o comportamento do app mudando o tamanho da fonte (Setting > Display > Font size) e depois restaurando o app em Recents.
-
Devido a um bug em versões anteriores do Android, o sistema não sinaliza gravações
em um soquete TCP na linha de execução principal como uma violação do modo estrito. O Android 7.0 corrige esse problema.
Os apps que exibem esse comportamento agora acionam uma
android.os.NetworkOnMainThreadException
. Geralmente, a realização de operações de rede na linha de execução principal é uma má ideia porque essas operações geralmente têm alta latência, o que causa ANRs e problemas. -
O padrão da família de métodos
Debug.startMethodTracing()
agora é armazenar a saída no diretório específico do pacote no armazenamento compartilhado, em vez de no nível superior do cartão SD. Isso significa que os apps não precisam mais solicitar a permissãoWRITE_EXTERNAL_STORAGE
para usar essas APIs. -
Muitas APIs de plataforma começaram a verificar grandes cargas úteis enviadas
em transações
Binder
, e o sistema agora gera novamenteTransactionTooLargeExceptions
comoRuntimeExceptions
, em vez de registrá-las ou suprimi-las silenciosamente. Um exemplo comum é armazenar dados demais emActivity.onSaveInstanceState()
, o que faz com queActivityThread.StopInfo
gere umaRuntimeException
quando o app é direcionado ao Android 7.0. -
Se um app postar tarefas
Runnable
para umaView
e aView
não estiver anexada a uma janela, o sistema colocará a tarefaRunnable
em fila com aView
. A tarefaRunnable
não será executada até que aView
seja anexada a uma janela. Este comportamento corrige os seguintes bugs:- Se um app publicasse em uma
View
de um encadeamento que não fosse o encadeamento de IU da janela pretendida, oRunnable
poderia ser executado no encadeamento errado. - Se a tarefa
Runnable
fosse publicada de um encadeamento que não fosse um encadeamento de looper, o app poderia expor a tarefaRunnable
.
- Se um app publicasse em uma
-
Se um app no Android 7.0 com a permissão
DELETE_PACKAGES
tentar excluir um pacote instalado por outro app, o sistema solicitará a confirmação do usuário. Nesse cenário, os apps precisam esperarSTATUS_PENDING_USER_ACTION
como o status de retorno quando invocamPackageInstaller.uninstall()
. - O provedor JCA Crypto foi descontinuado porque o único algoritmo dele, SHA1PRNG, é criptograficamente fraco. Os apps não podem mais usar o SHA1PRNG para (de forma não segura) derivar chaves, porque esse provedor não está mais disponível. Para mais informações, consulte a postagem do blog O provedor de segurança "Crypto" foi descontinuado no Android N.