Oltre a nuove funzionalità, Android 7.0 include una serie di modifiche al comportamento del sistema e delle API. Questo documento evidenzia alcune delle modifiche principali che è necessario comprendere e tenere presenti nelle proprie app.
Se in precedenza hai pubblicato un'app per Android, tieni presente che queste modifiche nella piattaforma potrebbero essere interessate da queste modifiche.
Batteria e memoria
Android 7.0 include modifiche del comportamento del sistema volte a migliorare la durata della batteria dei dispositivi e a ridurre l'utilizzo della RAM. Queste modifiche possono influire sull'accesso dell'app alle risorse di sistema, nonché sul modo in cui l'app interagisce con altre app tramite determinati intent impliciti.
Sospensione
Introdotta in Android 6.0 (livello API 23), la funzionalità Doze migliora la durata della batteria rinviando le attività di CPU e rete quando un utente lascia il dispositivo scollegato, fermo e con lo schermo spento. Android 7.0 introduce ulteriori miglioramenti alla funzionalità Sospensione applicando un sottoinsieme di limitazioni relative a CPU e rete quando il dispositivo è scollegato con lo schermo spento, ma non necessariamente è in movimento, ad esempio quando l'utente è fermo.
Quando il dispositivo è alimentato a batteria e lo schermo è spento per un determinato periodo di tempo, entra in modalità Sospensione e applica il primo sottoinsieme delle limitazioni: interrompe l'accesso alla rete delle app e rinvia i processi e le sincronizzazioni. Se il dispositivo rimane fermo per un determinato periodo di tempo dopo l'attivazione della modalità di sospensione, il sistema applica le restanti limitazioni relative alla sospensione a sveglie PowerManager.WakeLock
, AlarmManager
, GPS e ricerche di reti Wi-Fi. Indipendentemente dall'applicazione di alcune o tutte le limitazioni di sospensione, il sistema riattiva il dispositivo per brevi periodi di manutenzione, durante i quali alle applicazioni è consentito l'accesso alla rete ed è in grado di eseguire job/sincronizzazioni differite.
Tieni presente che l'attivazione dello schermo o il collegamento al dispositivo comporta l'uscita dalla modalità Sospensione e la rimozione di queste limitazioni di elaborazione. Il comportamento aggiuntivo non influisce sui consigli e sulle best practice per adattare l'app alla versione precedente di Doze introdotta in Android 6.0 (livello API 23), come spiegato nella sezione Ottimizzare sospensione e standby delle app. Devi comunque seguire questi consigli, ad esempio utilizzare Firebase Cloud Messaging (FCM) per inviare e ricevere messaggi, e iniziare a pianificare gli aggiornamenti per soddisfare il comportamento di sospensione aggiuntivo.
Progetto Svelte: ottimizzazioni in background
Android 7.0 rimuove tre trasmissioni implicite per contribuire a ottimizzare l'utilizzo della memoria e il consumo energetico. Questa modifica è necessaria perché le trasmissioni implicite spesso avviano app registrate per ascoltarle in background. La rimozione di questi annunci può migliorare notevolmente le prestazioni del dispositivo e l'esperienza utente.
I dispositivi mobili subiscono frequenti cambiamenti di connettività, ad esempio durante il passaggio dalla rete Wi-Fi ai dati mobili. Attualmente, le app possono monitorare le variazioni di connettività registrando un ricevitore per la trasmissione CONNECTIVITY_ACTION
implicita nel manifest. Poiché molte app si registrano per ricevere questa trasmissione, un singolo interruttore di rete può far sì che tutte si sveglino ed elaborino la trasmissione contemporaneamente.
Analogamente, nelle versioni precedenti di Android, le app potevano registrarsi per ricevere trasmissioni implicite ACTION_NEW_PICTURE
e ACTION_NEW_VIDEO
da altre app, come
Fotocamera. Quando un utente scatta una foto con l'app Fotocamera, queste app si riattivano per elaborare la trasmissione.
Per risolvere questi problemi, Android 7.0 applica le seguenti ottimizzazioni:
- Le app che hanno come target Android 7.0 (livello API 24) e versioni successive non ricevono trasmissioni
CONNECTIVITY_ACTION
se dichiarano il ricevitore della trasmissione nel manifest. Le app riceveranno comunque trasmissioniCONNECTIVITY_ACTION
se registrano il proprioBroadcastReceiver
conContext.registerReceiver()
e questo contesto è ancora valido. - Il sistema non invia più annunci
ACTION_NEW_PICTURE
oACTION_NEW_VIDEO
. Questa ottimizzazione riguarda tutte le app, non solo quelle che hanno come target Android 7.0.
Se la tua app utilizza uno di questi intent, devi rimuovere le dipendenze da questi intent il prima possibile in modo da poter scegliere correttamente i dispositivi Android 7.0 come target.
Il framework Android fornisce diverse soluzioni per ridurre la necessità di queste trasmissioni implicite. Ad esempio, l'API JobScheduler
fornisce un meccanismo solido per pianificare le operazioni di rete quando vengono soddisfatte condizioni specificate, come la connessione a una rete unmetered. Puoi anche utilizzare JobScheduler
per reagire ai cambiamenti che interessano i fornitori di contenuti.
Per scoprire di più sulle ottimizzazioni in background in Android 7.0 (livello API 24) e su come adattare la tua app, consulta Ottimizzazioni in background.
Modifiche alle autorizzazioni
Android 7.0 include modifiche alle autorizzazioni che potrebbero interessare la tua app.
Modifiche alle autorizzazioni del file system
Per migliorare la sicurezza dei file privati, la directory privata delle app destinate ad Android 7.0 o versioni successive ha limitato l'accesso (0700
). Questa impostazione impedisce la fuga di metadati dei file privati, ad esempio le dimensioni o l'esistenza dei file. Questa modifica delle autorizzazioni ha più effetti collaterali:
-
Le autorizzazioni dei file dei file privati non dovrebbero più essere concesse dal proprietario
e un tentativo di farlo utilizzando
MODE_WORLD_READABLE
e/oMODE_WORLD_WRITEABLE
attiverà unSecurityException
.Nota:al momento questa limitazione non è ancora stata applicata completamente. Le app possono comunque modificare le autorizzazioni alla propria directory privata utilizzando le API native o l'API
File
. Tuttavia, sconsigliamo vivamente di rilasciare le autorizzazioni per la directory privata. -
La trasmissione di URI
file://
al di fuori del dominio del pacchetto potrebbe lasciare il destinatario con un percorso non accessibile. Di conseguenza, i tentativi di passare un URIfile://
attivano unFileUriExposedException
. Il metodo consigliato per condividere i contenuti di un file privato è utilizzareFileProvider
. -
DownloadManager
non può più condividere file archiviati in privato in base al nome. Le applicazioni legacy potrebbero finire con un percorso non accessibile durante l'accesso aCOLUMN_LOCAL_FILENAME
. Le app che hanno come target Android 7.0 o versioni successive attivano unSecurityException
quando si tenta di accedere aCOLUMN_LOCAL_FILENAME
. Le applicazioni legacy che impostano il percorso di download su una posizione pubblica utilizzandoDownloadManager.Request.setDestinationInExternalFilesDir()
oDownloadManager.Request.setDestinationInExternalPublicDir()
possono comunque accedere al percorso inCOLUMN_LOCAL_FILENAME
, ma questo metodo è fortemente sconsigliato. Il modo preferito per accedere a un file esposto daDownloadManager
è utilizzareContentResolver.openFileDescriptor()
.
Condivisione di file tra app
Per le app destinate ad Android 7.0, il framework Android applica il criterio API StrictMode
che vieta l'esposizione di URI file://
all'esterno dell'app. Se un intent contenente un URI di file esce dall'app, l'app non riesce con un'eccezione FileUriExposedException
.
Per condividere file tra applicazioni, devi inviare un URI content://
e concedere un'autorizzazione di accesso temporanea all'URI. Il modo più semplice per concedere questa autorizzazione è
utilizzare la classe FileProvider
. Per ulteriori informazioni sulle autorizzazioni e sulla condivisione dei file, consulta la sezione Condivisione di file.
Accessibilità migliorata
Android 7.0 include modifiche volte a migliorare l'usabilità della piattaforma per gli utenti ipovedenti o con problemi di vista. In genere, queste modifiche non dovrebbero richiedere modifiche al codice nella tua app, ma dovresti esaminare queste funzionalità e testarle con la tua app per valutare il potenziale impatto sull'esperienza utente.
Zoom schermo
Android 7.0 consente agli utenti di impostare le Dimensioni del display che ingrandiscono o riducono tutti gli elementi sullo schermo, migliorando così l'accessibilità del dispositivo per gli utenti ipovedenti. Gli utenti non possono ingrandire lo schermo oltre la larghezza minima di sw320dp, ossia la larghezza di un Nexus 4, un comune telefono di medie dimensioni.
Quando la densità dei dispositivi cambia, il sistema invia una notifica alle app in esecuzione nei seguenti modi:
- Se un'app ha come target il livello API 23 o precedente, il sistema termina automaticamente tutti i processi in background. Ciò significa che se un utente esce da un'app di questo tipo per aprire la schermata Impostazioni e modifica l'impostazione Dimensioni visualizzazione, il sistema termina l'app come in una situazione di memoria insufficiente. Se l'app include processi in primo piano, il sistema invia una notifica a tali processi della modifica della configurazione come descritto in Gestione delle modifiche al runtime, come se l'orientamento del dispositivo fosse cambiato.
- Se un'app ha come target Android 7.0, tutti i relativi processi (in primo piano e in background) vengono avvisati della modifica della configurazione, come descritto nella sezione Gestione delle modifiche al runtime.
Per la maggior parte delle app non è necessario apportare modifiche per supportare questa funzionalità, purché le app seguano le best practice di Android. Aspetti specifici da verificare:
- Testa la tua app su un dispositivo con larghezza dello schermo
sw320dp
e assicurati che funzioni adeguatamente. - Quando la configurazione del dispositivo cambia, aggiorna tutte le informazioni memorizzate nella cache dipendenti dalla densità, ad esempio le bitmap memorizzate nella cache o le risorse caricate dalla rete. Verifica la presenza di modifiche alla configurazione quando l'app riprende dallo stato in pausa.
Nota: se memorizzi nella cache dati dipendenti dalla configurazione, è consigliabile includere metadati pertinenti, ad esempio le dimensioni dello schermo o la densità in pixel appropriate per questi dati. Il salvataggio di questi metadati ti consente di decidere se aggiornare i dati memorizzati nella cache dopo una modifica alla configurazione.
- Evita di specificare le dimensioni con unità px, poiché non si adattano alla densità dello schermo. Specifica invece le dimensioni con unità pixel indipendenti dalla densità (
dp
).
Impostazioni visive nella configurazione guidata
Android 7.0 include Impostazioni visive nella schermata di benvenuto, che consentono agli utenti di configurare le seguenti impostazioni di accessibilità su un nuovo dispositivo: Gesto di ingrandimento, Dimensioni carattere, Dimensioni display e TalkBack. Questa modifica aumenta la visibilità di bug relativi a diverse impostazioni dello schermo. Per valutare l'impatto di questa funzionalità, devi testare le tue app con queste impostazioni abilitate. Puoi trovare le impostazioni in Impostazioni > Accessibilità.
Collegamento delle app NDK alle librerie della piattaforma
A partire dalla versione 7.0 di Android, il sistema impedisce il collegamento dinamico delle app con librerie non NDK e questo potrebbe causare l'arresto anomalo dell'app. Questo cambiamento di comportamento mira a creare un'esperienza coerente con le app tra gli aggiornamenti della piattaforma e i diversi dispositivi. Anche se il codice potrebbe non essere collegato a librerie private, è possibile che l'operazione venga eseguita da una libreria statica di terze parti nella tua app. Pertanto, tutti gli sviluppatori dovrebbero verificare che le loro app non abbiano arresti anomali sui dispositivi con Android 7.0. Se la tua app utilizza codice nativo, dovresti utilizzare solo API NDK pubbliche.
La tua app potrebbe tentare di accedere alle API della piattaforma privata in tre modi:
- La tua app accede direttamente alle librerie private della piattaforma. Devi aggiornare l'app in modo da includere la propria copia di queste librerie o utilizzare le API NDK pubbliche.
- La tua app utilizza una libreria di terze parti che accede alle librerie private di piattaforme. Anche se hai la certezza che la tua app non acceda direttamente alle librerie private, devi comunque testare la tua app per questo scenario.
- La tua app fa riferimento a una libreria non inclusa nel relativo APK. Ad esempio, questo può accadere se hai provato a utilizzare la tua copia di OpenSSL ma hai dimenticato di raggrupparla con l'APK della tua app. L'app potrebbe essere eseguita normalmente su versioni
della piattaforma Android che includono
libcrypto.so
. Tuttavia, l'app potrebbe arrestarsi in modo anomalo nelle versioni successive di Android che non includono questa libreria (ad esempio Android 6.0 e versioni successive). Per risolvere il problema, assicurati di raggruppare tutte le librerie non NDK nell'APK.
Le app non devono utilizzare librerie native non incluse nell'NDK perché potrebbero cambiare o essere rimosse tra le diverse versioni di Android. Il passaggio da OpenSSL a BoringSSL è un esempio di questa modifica. Inoltre, poiché non esistono requisiti di compatibilità per le librerie di piattaforme non incluse nell'NDK, dispositivi diversi possono offrire diversi livelli di compatibilità.
Per ridurre l'impatto che questa limitazione potrebbe avere sulle app attualmente rilasciate, un insieme di librerie che vengono utilizzate in modo significativo, come libandroid_runtime.so
, libcutils.so
, libcrypto.so
e libssl.so
, sono temporaneamente accessibili su Android 7.0 (livello API 24) per le app che hanno come target il livello API 23 o precedente. Se la tua app carica una di queste librerie, logcat genera un avviso
e sul dispositivo di destinazione viene visualizzato un avviso popup per avvisarti. Se vedi questi avvisi, devi aggiornare l'app in modo da includere la propria copia di queste librerie o utilizzare solo le API NDK pubbliche. Le release future della piattaforma Android potrebbero limitare completamente l'utilizzo delle librerie private e causare l'arresto anomalo della tua app.
Tutte le app generano un errore di runtime quando chiamano un'API che non è né pubblica né temporaneamente accessibile. Il risultato è che
System.loadLibrary
e dlopen(3)
restituiscono entrambi
NULL
e potrebbero causare l'arresto anomalo dell'app. Controlla il codice dell'app per rimuovere l'utilizzo delle API della piattaforma privata e testare attentamente le tue app utilizzando un dispositivo o un emulatore con Android 7.0 (livello API 24). Se non hai la certezza che la tua app utilizzi librerie private, puoi controllare logcat per identificare l'errore di runtime.
La seguente tabella descrive il comportamento previsto di un'app in base all'utilizzo di librerie native private e al livello API target (android:targetSdkVersion
).
Librerie | Livello API target | Accesso runtime tramite linker dinamico | Comportamento di Android 7.0 (livello API 24) | Comportamento futuro della piattaforma Android |
---|---|---|---|---|
NDK pubblico | Qualsiasi | Accessibile | Funziona come previsto | Funziona come previsto |
Privata (librerie private accessibili temporaneamente) | 23 o inferiore | Temporaneamente accessibile | Funziona come previsto, ma viene visualizzato un avviso logcat. | Errore di runtime |
Privata (librerie private accessibili temporaneamente) | 24 o successiva | Con restrizioni | Errore di runtime | Errore di runtime |
Privato (altro) | Qualsiasi | Con restrizioni | Errore di runtime | Errore di runtime |
Controllare se l'app utilizza librerie private
Per aiutarti a identificare i problemi di caricamento delle librerie private, logcat potrebbe generare un avviso o un errore di runtime. Ad esempio, se la tua app ha come target il livello API 23 o precedente e tenta di accedere a una libreria privata su un dispositivo con Android 7.0, potresti visualizzare un avviso simile al seguente:
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
Questi avvisi logcat indicano quale libreria sta tentando di accedere a un'API della piattaforma privata, ma non causeranno l'arresto anomalo dell'app. Se l'app ha come target il livello API 24 o successivo, tuttavia, logcat genera il seguente errore di runtime e l'app potrebbe arrestarsi in modo anomalo:
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)
Potresti anche vedere questi output logcat se la tua app utilizza librerie di terze parti che si collegano dinamicamente alle API private della piattaforma. Lo strumento di lettura in Android 7.0DK consente di generare un elenco di tutte le librerie condivise collegate dinamicamente per un determinato file .so
eseguendo questo comando:
aarch64-linux-android-readelf -dW libMyLibrary.so
Aggiorna la tua app
Di seguito sono riportati alcuni passaggi che puoi svolgere per correggere questi tipi di errori e assicurarti che l'app non si arresti in modo anomalo negli aggiornamenti futuri della piattaforma:
- Se la tua app utilizza librerie di piattaforme private, devi aggiornarla in modo da includere la propria copia di tali librerie o utilizzare le API NDK pubbliche.
- Se la tua app utilizza una libreria di terze parti che accede a simboli privati, contatta l'autore della raccolta per aggiornare la raccolta.
- Assicurati di pacchettizzare tutte le tue librerie non NDK con il tuo APK.
- Utilizza le funzioni JNI standard anziché
getJavaVM
egetJNIEnv
dilibandroid_runtime.so
:AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or JavaVM::AttachCurrentThread from <jni.h>.
- Usa
__system_property_get
anziché il simbolo privatoproperty_get
dilibcutils.so
. A questo scopo, usa__system_property_get
con quanto segue:#include <sys/system_properties.h>
Nota: la disponibilità e i contenuti delle proprietà di sistema non vengono testati tramite CTS. Una soluzione migliore sarebbe evitare di utilizzare tutte queste proprietà.
- Utilizza una versione locale del simbolo
SSL_ctrl
dilibcrypto.so
. Ad esempio, devi collegarelibcyrpto.a
in modo statico nel file.so
oppure includere una versione dilibcrypto.so
collegata in modo dinamico da BoringSSL/OpenSSL e pacchettizzarla nel tuo APK.
Android for Work
Android 7.0 contiene modifiche per le app destinate ad Android for Work, tra cui modifiche all'installazione dei certificati, alla reimpostazione della password, alla gestione utenti secondaria e all'accesso agli identificatori dei dispositivi. Se sviluppi app per ambienti Android for Work, dovresti rivedere queste modifiche e modificare la tua app di conseguenza.
- Devi installare un programma di installazione dei certificati delegato prima che il DPC possa impostarlo. Per le app del profilo e del proprietario del dispositivo che hanno come target Android 7.0 (livello API 24), devi installare il programma di installazione dei certificati con delega prima che il controller dei criteri dei dispositivi (DPC) chiami
DevicePolicyManager.setCertInstallerPackage()
. Se il programma di installazione non è già installato, il sistema genera unIllegalArgumentException
. - La reimpostazione delle limitazioni della password per gli amministratori dei dispositivi ora si applica ai proprietari
del profilo. Gli amministratori dei dispositivi non possono più utilizzare
DevicePolicyManager.resetPassword()
per cancellare le password o modificare quelle già impostate. Gli amministratori dei dispositivi possono comunque impostare una password, ma solo se il dispositivo non dispone di password, PIN o sequenza. - I proprietari di dispositivi e profili possono gestire gli account anche se sono impostate delle limitazioni. I proprietari dei dispositivi e dei profili possono chiamare l'API Account Management anche se sono applicate limitazioni per gli utenti
DISALLOW_MODIFY_ACCOUNTS
. - I proprietari di dispositivi possono gestire più facilmente gli utenti secondari. Quando un dispositivo viene eseguito in modalità Proprietario del dispositivo, la limitazione
DISALLOW_ADD_USER
viene impostata automaticamente. Questo impedisce agli utenti di creare utenti secondari non gestiti. Inoltre, i metodiCreateUser()
ecreateAndInitializeUser()
sono deprecati e vengono sostituiti dal nuovo metodoDevicePolicyManager.createAndManageUser()
. - I proprietari dei dispositivi possono accedere agli identificatori dei dispositivi. Il proprietario di un dispositivo può accedere
all'indirizzo MAC Wi-Fi di un dispositivo utilizzando
DevicePolicyManager.getWifiMacAddress()
. Se il Wi-Fi non è mai stato attivato sul dispositivo, questo metodo restituisce il valorenull
. - L'impostazione Modalità di lavoro controlla l'accesso alle app di lavoro. Quando la modalità di lavoro non è attiva, Avvio app di sistema indica che le app di lavoro non sono disponibili disattivandole. La riattivazione della modalità di lavoro ripristina il comportamento normale.
- Quando installi un file PKCS #12 contenente una catena di certificati client e la chiave privata corrispondente dalla UI delle impostazioni, il certificato CA nella catena non viene più installato nello spazio di archiviazione delle credenziali attendibili. Ciò non influisce sul risultato di
KeyChain.getCertificateChain()
quando le app tentano di recuperare la catena di certificati client in un secondo momento. Se necessario, il certificato CA deve essere installato separatamente nell'archiviazione di credenziali attendibili tramite la UI Impostazioni, con un formato con codifica DER e un'estensione del file .crt o .cer. - A partire da Android 7.0, la registrazione e l'archiviazione delle impronte vengono gestite in base all'utente. Se il client DPC (Device Policy Client) di un proprietario del profilo ha come target il livello API 23 (o precedente) su un dispositivo con Android 7.0 (livello API 24), l'utente può comunque impostare l'impronta sul dispositivo, ma le applicazioni di lavoro non possono accedere all'impronta del dispositivo. Se il DPC ha come target il livello API 24 o superiore, l'utente può impostare l'impronta in modo specifico per il profilo di lavoro andando su Impostazioni > Sicurezza > Sicurezza del profilo di lavoro.
DevicePolicyManager.getStorageEncryptionStatus()
restituisce un nuovo stato di crittografia,ENCRYPTION_STATUS_ACTIVE_PER_USER
, che indica che la crittografia è attiva e che la chiave di crittografia è legata all'utente. Il nuovo stato viene restituito solo se il DPC ha come target il livello API 24 o superiore. Per le app che hanno come target livelli API precedenti, viene restituitoENCRYPTION_STATUS_ACTIVE
anche se la chiave di crittografia è specifica per l'utente o il profilo.- In Android 7.0, diversi metodi che in genere influirebbero sull'intero dispositivo si comportano in modo diverso se sul dispositivo è installato un profilo di lavoro con una verifica di lavoro separata. Questi metodi non interessano l'intero dispositivo, ma si applicano solo al profilo di lavoro. L'elenco completo di questi metodi è disponibile nella documentazione di
DevicePolicyManager.getParentProfileInstance()
. Ad esempio,DevicePolicyManager.lockNow()
blocca solo il profilo di lavoro, anziché l'intero dispositivo. Per ognuno di questi metodi, puoi ottenere il comportamento precedente chiamando il metodo sull'istanza padre diDevicePolicyManager
; puoi ottenere questo comportamento padre chiamandoDevicePolicyManager.getParentProfileInstance()
. Ad esempio, se chiami il metodolockNow()
dell'istanza padre, l'intero dispositivo verrà bloccato.
Conservazione delle annotazioni
Android 7.0 corregge un bug per cui la visibilità delle annotazioni veniva ignorata. Questo problema ha consentito al runtime di accedere ad annotazioni che non avrebbe dovuto essere in grado di fare. Queste annotazioni includevano:
VISIBILITY_BUILD
: dovrebbe essere visibile solo al momento della creazione.VISIBILITY_SYSTEM
: destinata a essere visibile in fase di runtime, ma solo al sistema sottostante.
Se la tua app si è affidata a questo comportamento, aggiungi un criterio di conservazione alle annotazioni che devono essere disponibili in fase di runtime. A tale scopo, utilizza @Retention(RetentionPolicy.RUNTIME)
.
Modifiche alla configurazione predefinita TLS/SSL
Android 7.0 apporta le seguenti modifiche alla configurazione TLS/SSL predefinita utilizzata dalle app per HTTPS e altro traffico TLS/SSL:
- Le suite di crittografia RC4 sono ora disattivate.
- Le suite di crittografia CHACHA20-POLY1305 sono ora attivate.
La disattivazione di RC4 per impostazione predefinita potrebbe causare interruzioni della connettività HTTPS o TLS/SSL quando il server non negozia suite di crittografia moderne. La soluzione preferita consiste nel migliorare la configurazione del server per abilitare suite di crittografia e protocolli più potenti e moderni. Idealmente, dovrebbero essere attivati TLSv1.2 e AES-GCM e dovrebbero essere attivate le suite di crittografia Forward Secrecy (ECDHE) e preferite.
In alternativa, puoi modificare l'app in modo da utilizzare un SSLSocketFactory
personalizzato per comunicare con il server. La fabbrica dovrebbe essere progettata per creare istanze SSLSocket
con alcune delle suite di crittografia richieste dal server abilitate, oltre alle suite di crittografia predefinite.
Nota. Queste modifiche non riguardano WebView
.
App che hanno come target Android 7.0
Queste modifiche al comportamento si applicano esclusivamente alle app destinate ad Android 7.0 (livello API 24) o versioni successive. Le app che compilano su Android 7.0
o che impostano targetSdkVersion
su Android 7.0 o versioni successive devono modificare
le app per supportare correttamente questi comportamenti, ove applicabile all'app.
Modifiche alla serializzazione
Android 7.0 (livello API 24) ha corretto un bug nel calcolo del valore serialVersionUID predefinito per cui non corrispondeva alla specifica.
Le classi che implementano Serializable
e non specificano un campo serialVersionUID
esplicito potrebbero notare una modifica nel valore serialVersionUID predefinito, il che comporterebbe la generazione di un'eccezione quando si tenta di deserializzare le istanze della classe che sono state serializzate in una versione precedente o da un'app che ha come target una versione precedente. Il messaggio di errore sarà simile al seguente:
local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567
Per risolvere questi problemi è necessario aggiungere un campo serialVersionUID
a qualsiasi classe interessata con il valore stream classdesc
serialVersionUID
dal messaggio di errore, ad esempio 1234
in questo caso. Questa modifica è conforme a tutti i suggerimenti di buone pratiche per la scrittura del codice di serializzazione e funzionerà su tutte le versioni di Android.
Il bug specifico corretto era correlato alla presenza di metodi di inizializzazione statici, ad esempio <clinit>
. Secondo la specifica, la presenza o l'assenza di un metodo di inizializzazione statico nella classe influirà sul valore serialVersionUID predefinito calcolato per quella classe.
Prima della correzione del bug, il calcolo controllava anche la super classe di un inizializzatore statico, se una classe non ne aveva uno.
Per chiarire, questa modifica non riguarda le app destinate ai livelli API 23 o precedenti, alle classi che hanno un campo serialVersionUID
o alle classi che hanno un metodo di inizializzatore statico.
Altri punti importanti
- Quando un'app è in esecuzione su Android 7.0, ma ha come target un livello API inferiore e l'utente cambia le dimensioni di visualizzazione, il processo dell'app viene interrotto. L'app deve essere in grado di gestire questo scenario correttamente. In caso contrario, si arresta in modo anomalo quando l'utente lo ripristina da Recenti.
Devi testare l'app per assicurarti che questo comportamento non si verifichi. Per farlo, causa un arresto anomalo identico quando chiudi manualmente l'app tramite DCM.
Le app che hanno come target Android 7.0 (livello API 24) e versioni successive non vengono terminate automaticamente con le variazioni della densità, ma potrebbero comunque rispondere male alle modifiche alla configurazione.
- Le app su Android 7.0 dovrebbero essere in grado di gestire agevolmente le modifiche alla configurazione e non dovrebbero arrestarsi in modo anomalo negli avvii successivi. Puoi verificare il comportamento dell'app modificando le dimensioni dei caratteri (Impostazioni > Display > Dimensioni carattere), quindi ripristinando l'app da Recenti.
-
A causa di un bug nelle versioni precedenti di Android, il sistema non ha segnalato la scrittura su un socket TCP nel thread principale come violazione della modalità restrittiva. Android 7.0 corregge questo bug.
Le app che mostrano questo comportamento ora generano un
android.os.NetworkOnMainThreadException
. In genere, eseguire operazioni di rete sul thread principale è una cattiva idea perché di solito hanno un'elevata latenza che causa errori ANR e jank. -
Per impostazione predefinita, la famiglia di metodi
Debug.startMethodTracing()
memorizza l'output nella directory specifica del pacchetto nello spazio di archiviazione condiviso, anziché nel livello superiore della scheda SD. Ciò significa che le app non dovranno più richiedere l'autorizzazioneWRITE_EXTERNAL_STORAGE
per utilizzare queste API. -
Molte API delle piattaforme hanno iniziato a controllare l'invio di payload di grandi dimensioni attraverso le transazioni
Binder
e il sistema ora restituisceTransactionTooLargeExceptions
comeRuntimeExceptions
, invece di registrarli o ignorarli in modo invisibile. Un esempio comune è l'archiviazione di troppi dati inActivity.onSaveInstanceState()
, per cuiActivityThread.StopInfo
restituisceRuntimeException
quando la tua app ha come target Android 7.0. -
Se un'app pubblica
Runnable
attività in unView
e l'elementoView
non è collegato a una finestra, il sistema mette in coda l'attivitàRunnable
conView
; l'attivitàRunnable
non viene eseguita finché laView
non viene collegata a una finestra. Questo comportamento consente di correggere i seguenti bug:- Se un'app viene pubblicata in un
View
da un thread diverso dal thread dell'interfaccia utente della finestra prevista, laRunnable
potrebbe essere eseguita nel thread sbagliato. - Se l'attività
Runnable
è stata pubblicata da un thread diverso da un thread del looper, l'app potrebbe esporre l'attivitàRunnable
.
- Se un'app viene pubblicata in un
-
Se su Android 7.0 con autorizzazione
DELETE_PACKAGES
un'app prova a eliminare un pacchetto, ma quel pacchetto era installato da un'altra app, il sistema richiede la conferma dell'utente. In questo scenario, le app dovrebbero aspettarsiSTATUS_PENDING_USER_ACTION
come stato restituito quando richiamanoPackageInstaller.uninstall()
. - Il provider JCA chiamato Crypto è deprecato perché il suo unico algoritmo, SHA1PRNG, è crittograficamente debole. Le app non possono più utilizzare SHA1PRNG per derivare le chiavi (in modo non sicuro), perché questo provider non è più disponibile. Per maggiori informazioni, consulta il blog post Il provider di sicurezza "Crypto" è deprecato in Android N.