Oltre a nuove funzionalità e caratteristiche, Android 7.0 include una serie di modifiche del comportamento del sistema e delle API. Questo documento evidenzia alcune delle modifiche principali che dovresti comprendere e tenere presenti nelle tue app.
Se hai già pubblicato un'app per Android, tieni presente che la tua app potrebbe essere interessata da queste modifiche nella piattaforma.
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 e 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 posticipando 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 di CPU e rete quando il dispositivo è scollegato con lo schermo spento, ma non necessariamente è fermo, ad esempio quando è in viaggio.
Quando un dispositivo è alimentato a batteria e lo schermo è spento per un determinato periodo di tempo, il dispositivo entra in modalità Sospensione e applica il primo sottoinsieme di limitazioni: interrompe l'accesso alla rete delle app e reinvia job e sincronizzazioni. Se il dispositivo rimane fermo per un determinato periodo di tempo dopo l'attivazione della modalità Sospensione, il sistema applica il resto delle limitazioni relative alla sospensione a PowerManager.WakeLock
,
sveglie 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 e possono eseguire job/sincronizzazioni differite.
Tieni presente che l'attivazione dello schermo o il collegamento del dispositivo comporta l'uscita dalla modalità Sospensione e la rimozione di queste limitazioni relative all'elaborazione. Il comportamento aggiuntivo non influisce su suggerimenti e best practice per adattare l'app alla versione precedente di Doze introdotta in Android 6.0 (livello API 23), come spiegato nella sezione Ottimizzazione per sospensione e standby delle app. Devi comunque seguire questi suggerimenti, 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.
Project Svelte: ottimizzazioni in background
Android 7.0 rimuove tre trasmissioni implicite per ottimizzare l'utilizzo della memoria e il consumo energetico. Questa modifica è necessaria perché le trasmissioni implicite spesso avviano app che sono state registrate per ascoltarle in background. La rimozione di questi broadcast può migliorare notevolmente le prestazioni del dispositivo e l'esperienza utente.
I dispositivi mobili subiscono frequenti cambi di connettività, ad esempio in caso di passaggio dalla rete Wi-Fi ai dati mobili e viceversa. Attualmente, le app possono monitorare le variazioni di connettività registrando un ricevitore per la trasmissione CONNECTIVITY_ACTION
implicita nel proprio manifest. Poiché molte app si registrano per ricevere questa trasmissione, un singolo switch di rete può far sì che tutte si attivino ed elaborino la trasmissione contemporaneamente.
Analogamente, nelle versioni precedenti di Android, le app potevano registrarsi per ricevere annunci ACTION_NEW_PICTURE
e ACTION_NEW_VIDEO
impliciti da altre app, ad esempio Fotocamera. Quando un utente scatta una foto con l'app Fotocamera, queste app si attivano 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 di 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 influisce su tutte le app, non solo su 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 per poter scegliere correttamente come target i dispositivi Android 7.0.
Il framework Android offre 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 apportati ai fornitori di contenuti.
Per saperne di più sulle ottimizzazioni in background in Android 7.0 (livello API 24) e su come adattare la tua app, consulta la pagina 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, l'accesso alla directory privata delle app destinate ad Android 7.0 o versioni successive è limitato (0700
). Questa impostazione impedisce la perdita di metadati dei file privati, ad esempio le dimensioni o l'esistenza dei file. Questa modifica delle autorizzazioni ha diversi effetti collaterali:
-
Le autorizzazioni dei file privati non dovrebbero più essere concesse dal proprietario e, se si tenta di farlo utilizzando
MODE_WORLD_READABLE
e/oMODE_WORLD_WRITEABLE
, verrà attivato un'SecurityException
.Nota:al momento questa limitazione non è ancora stata applicata completamente. Le app possono comunque modificare le autorizzazioni nella propria directory privata utilizzando le API native o l'API
File
. Tuttavia, sconsigliamo vivamente di allentare le autorizzazioni per la directory privata. -
La trasmissione di URI
file://
all'esterno 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 file. Le applicazioni legacy potrebbero finire con un percorso non accessibile quando accedono 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 la posizione di download su una posizione pubblica utilizzandoDownloadManager.Request.setDestinationInExternalFilesDir()
oDownloadManager.Request.setDestinationInExternalPublicDir()
possono comunque accedere al percorso inCOLUMN_LOCAL_FILENAME
, ma questo metodo è vivamente sconsigliato. Il modo preferito per accedere a un file esposto daDownloadManager
è utilizzareContentResolver.openFileDescriptor()
.
Condivisione di file tra app
Per le app che hanno come target Android 7.0, il framework Android applica il criterio dell'API StrictMode
che vieta l'esposizione degli URI file://
all'esterno dell'app. Se un intent contenente l'URI di un file lascia l'app, l'app non va a buon fine 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, vedi Condivisione dei file.
Accessibilità migliorata
Android 7.0 include modifiche volte a migliorare l'usabilità della piattaforma per gli utenti ipovedenti o con disabilità visiva. In genere queste modifiche non dovrebbero richiedere modifiche al codice nell'app, ma ti consigliamo di esaminare queste funzionalità e testarle con l'app per valutare il potenziale impatto sull'esperienza utente.
Zoom schermo
Android 7.0 consente agli utenti di impostare le Dimensioni del display in modo da ingrandire o ridurre tutti gli elementi sullo schermo, migliorando così l'accessibilità del dispositivo per gli utenti ipovedenti. Gli utenti non possono eseguire lo zoom dello schermo oltre la larghezza minima di sw320dp, ossia la larghezza di un Nexus 4, un comune telefono di medie dimensioni.
Quando la densità del dispositivo cambia, il sistema avvisa le app in esecuzione nei seguenti modi:
- Se un'app ha come target il livello API 23 o un livello 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 farebbe in una situazione di memoria insufficiente. Se nell'app sono presenti processi in primo piano, il sistema notifica a questi processi la 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 processi (in primo piano e in background) vengono avvisati della modifica della configurazione, come descritto in Gestione delle modifiche al runtime.
Per la maggior parte delle app non è necessario apportare modifiche per supportare questa funzionalità, a condizione che 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 in modo adeguato. - Quando la configurazione del dispositivo cambia, aggiorna le informazioni memorizzate nella cache che dipendono dalla densità, ad esempio le informazioni memorizzate nella cache o le risorse caricate dalla rete. Verifica la presenza di modifiche alla configurazione quando l'app viene ripristinata dallo stato in pausa.
Nota: se memorizzi nella cache dati dipendenti dalla configurazione, è consigliabile includere i metadati pertinenti, come le dimensioni dello schermo o la densità in pixel appropriati. 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 vengono scalate in base alla densità dello schermo. Specifica invece le dimensioni con unità pixel indipendenti dalla densità (
dp
).
Impostazioni visive nella configurazione guidata
Android 7.0 include le impostazioni visive nella schermata di benvenuto, in cui gli utenti possono configurare le seguenti impostazioni di accessibilità su un nuovo dispositivo: Gesto di ingrandimento, Dimensione carattere, Dimensioni display e TalkBack. Questa modifica aumenta la visibilità dei 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 da Android 7.0, il sistema impedisce il collegamento dinamico delle app a librerie non NDK, causando possibili arresti anomali dell'app. Questo cambiamento di comportamento mira a creare un'esperienza coerente con le app negli aggiornamenti della piattaforma e su dispositivi diversi. Anche se il codice non rimanda alle librerie private, è possibile che una libreria statica di terze parti nella tua app lo faccia. Pertanto, tutti gli sviluppatori dovrebbero controllare che le loro app non abbiano un arresto anomalo sui dispositivi con Android 7.0. Se la tua app utilizza codice nativo, devi utilizzare solo API NDK pubbliche.
Sono tre i modi in cui la tua app potrebbe tentare di accedere alle API delle piattaforme private:
- La tua app accede direttamente alle librerie di piattaforme private. Devi aggiornare l'app includendo la relativa copia di queste librerie o utilizzare le API NDK pubbliche.
- La tua app utilizza una libreria di terze parti che accede alle librerie private delle piattaforme. Anche se hai la certezza che la tua app non acceda direttamente alle librerie private, devi comunque testare l'app per questo scenario.
- La tua app fa riferimento a una libreria non inclusa nel relativo APK. Ad esempio, questo potrebbe accadere se hai provato a utilizzare la tua copia di OpenSSL ma hai dimenticato di raggrupparlo con l'APK della tua app. L'app potrebbe funzionare 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 con il tuo APK.
Le app non devono utilizzare librerie native non incluse nell'NDK perché potrebbero cambiare o essere rimosse tra versioni diverse 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 livelli diversi di compatibilità.
Per ridurre l'impatto che questa limitazione potrebbe avere sulle app attualmente rilasciate, un insieme di librerie che registrano un uso 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 versioni precedenti. 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. Di conseguenza, 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 delle piattaforme private e testare accuratamente le tue app utilizzando un dispositivo o un emulatore con Android 7.0 (livello API 24). Se non sai con certezza se la tua app utilizza 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 relativo livello API target (android:targetSdkVersion
).
Librerie | Livello API target | Accesso al runtime tramite linker dinamico | Comportamento di Android 7.0 (livello API 24) | Comportamento futuro della piattaforma Android |
---|---|---|---|---|
NDK pubblico | Qualsiasi | Accessibili | Funziona come previsto | Funziona come previsto |
Privata (librerie private accessibili temporaneamente) | 23 o meno | Temporaneamente accessibile | Funziona come previsto, ma viene visualizzato un avviso logcat. | Errore di runtime |
Privata (librerie private accessibili temporaneamente) | 24 o successiva | Con limitazioni | Errore di runtime | Errore di runtime |
Privato (altro) | Qualsiasi | Con limitazioni | 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 di una piattaforma privata, ma non causano l'arresto anomalo dell'app. Tuttavia, se l'app ha come target il livello API 24 o versioni successive, logcat genera il seguente errore di runtime e la tua 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 della piattaforma privata. Lo strumento Readelf di Android 7.0DK consente di generare un elenco di tutte le librerie condivise collegate dinamicamente di 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 seguire 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 della piattaforma private, devi aggiornarla in modo da includere una copia personale di queste 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 libreria per aggiornare la libreria.
- Assicurati di pacchettizzare tutte le librerie non NDK nel tuo APK.
- Usa le funzioni JNI standard anziché
getJavaVM
egetJNIEnv
dalibandroid_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 completamente di utilizzare queste proprietà.
- Utilizza una versione locale del simbolo
SSL_ctrl
dilibcrypto.so
. Ad esempio, dovresti collegare in modo staticolibcyrpto.a
nel file.so
oppure includere una versione dilibcrypto.so
a collegamento 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 delle password, alla gestione utenti secondaria e all'accesso agli identificatori dei dispositivi. Se stai creando app per ambienti Android for Work, devi esaminare queste modifiche e modificare l'app di conseguenza.
- Devi installare un programma di installazione del certificato 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 del certificato delegato prima che il controller
dei criteri dei dispositivi (DPC) chiami
DevicePolicyManager.setCertInstallerPackage()
. Se il programma di installazione non è già installato, il sistema genera un messaggioIllegalArgumentException
. - Le limitazioni della reimpostazione della password per gli amministratori dei dispositivi ora vengono applicate 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 ha password, PIN o sequenza. - I proprietari di dispositivi e profili possono gestire gli account anche se sono impostate delle limitazioni. I proprietari di dispositivi e profili possono chiamare l'API Account Management anche se sono in vigore le limitazioni utente di
DISALLOW_MODIFY_ACCOUNTS
. - I proprietari dei dispositivi possono gestire più facilmente gli utenti secondari. Quando un dispositivo è in esecuzione 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à Lavoro controlla l'accesso alle app di lavoro. Quando la modalità Lavoro non è attiva, Avvio app di sistema indica che le app di lavoro non sono disponibili rendendole selezionabili in grigio. Se abiliti di nuovo la modalità di lavoro, verrà ripristinato il comportamento normale.
- Quando installi un file PKCS #12 contenente una catena di certificati client e la chiave privata corrispondente dall'interfaccia utente Impostazioni, il certificato CA nella catena non viene più installato nell'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 richiesto, il certificato CA deve essere installato separatamente nell'archiviazione delle credenziali attendibili tramite l'interfaccia utente delle 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 sono gestite in base all'utente. Se il client DPC (Device Policy Client) del proprietario di un 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 versioni successive, l'utente può impostare l'impronta digitale in modo specifico per il profilo di lavoro andando su Impostazioni > Sicurezza > Sicurezza del profilo di lavoro.
DevicePolicyManager.getStorageEncryptionStatus()
restituisce un nuovo stato di crittografiaENCRYPTION_STATUS_ACTIVE_PER_USER
, a indicare 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 solitamente incidono sull'intero dispositivo si comportano in modo diverso se sul dispositivo è installato un profilo di lavoro con una verifica di lavoro separata. Anziché interessare l'intero dispositivo, questi metodi 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é bloccare l'intero dispositivo. Per ognuno di questi metodi, puoi ottenere il comportamento precedente chiamando il metodo sull'istanza padre diDevicePolicyManager
; puoi ottenere questo metodo padre chiamandoDevicePolicyManager.getParentProfileInstance()
. Ad esempio, se chiami il metodolockNow()
dell'istanza padre, l'intero dispositivo viene 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 a cui non avrebbe dovuto essere. Queste annotazioni includevano:
VISIBILITY_BUILD
: dovrebbero essere visibili solo al momento della creazione.VISIBILITY_SYSTEM
: deve essere visibile in fase di runtime, ma solo al sistema sottostante.
Se la tua app ha fatto affidamento su questo comportamento, aggiungi alle annotazioni un criterio di conservazione che deve essere disponibile in fase di runtime. Per farlo, devi utilizzare @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 abilitate.
La disattivazione di RC4 per impostazione predefinita potrebbe causare interruzioni nella 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ù solidi e moderni. Idealmente, TLSv1.2 e AES-GCM dovrebbero essere attivati e le suite di crittografia Forward Secrecy (ECDHE) dovrebbero essere abilitate e preferite.
Un'alternativa è modificare l'app per utilizzare un SSLSocketFactory
personalizzato per comunicare con il server. Il
dati di fabbrica dovrebbe essere progettato per creare istanze SSLSocket
che dispongono di alcune delle suite di crittografia richieste dal server
abilitate, oltre alle suite di crittografia predefinite.
Nota. Queste modifiche non riguardano WebView
.
App destinate ad 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 vengono compilate in base ad Android 7.0 o impostano targetSdkVersion
su Android 7.0 o versioni successive devono modificare le proprie 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 in cui non corrispondeva alla specifica.
Le classi che implementano Serializable
e non specificano un campo serialVersionUID
esplicito potrebbero vedere una modifica nel valore serialVersionUID predefinito, il che causerebbe un'eccezione quando si tenta di deserializzare le istanze della classe che sono state serializzate su una versione precedente o serializzate 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 prassi per la scrittura del codice di serie e funzionerà su tutte le versioni di Android.
Il bug specifico corretto riguardava la presenza di metodi di inizializzazione statici, ad esempio <clinit>
. In base alla 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 superclasse per un inizializzatore statico, se una classe non ne aveva uno.
Per chiarire, questa modifica non interessa le app che hanno come target i livelli API 23 o precedenti, le classi che hanno un campo serialVersionUID
o le classi con un metodo di inizializzazione statico.
Altri aspetti 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.
Dovresti testare l'app per assicurarti che questo comportamento non si verifichi. Puoi farlo causando un arresto anomalo identico quando termini l'app manualmente tramite DCM.
Le app che hanno come target Android 7.0 (livello API 24) e versioni successive non vengono terminate automaticamente in caso di 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 agli 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 segnalava la scrittura in un socket TCP nel thread principale come violazione in modalità rigida. 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é queste operazioni di solito hanno un'elevata latenza che causa errori ANR e jank. -
La famiglia di metodi
Debug.startMethodTracing()
ora imposta l'archiviazione dell'output nella directory specifica del pacchetto nello spazio di archiviazione condiviso, anziché nel livello superiore della scheda SD. Ciò significa che le app non devono 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
, anziché registrarli o sopprimerli in modalità silenziosa. Un esempio comune è l'archiviazione di troppi dati inActivity.onSaveInstanceState()
, il che fa sì cheActivityThread.StopInfo
restituisca unRuntimeException
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 accoda l'attivitàRunnable
con l'elementoView
; l'attivitàRunnable
non viene eseguita finché laView
non viene collegata a una finestra. Questo comportamento corregge i seguenti bug:- Se un'app ha pubblicato un'app in un
View
da un thread diverso dal thread di interfaccia utente della finestra prevista, l'elementoRunnable
potrebbe essere eseguito sul thread sbagliato. - Se l'attività
Runnable
viene pubblicata da un thread diverso da un thread del looper, l'app potrebbe esporre l'attivitàRunnable
.
- Se un'app ha pubblicato un'app in un
-
Se un'app su Android 7.0 con autorizzazione
DELETE_PACKAGES
tenta di eliminare un pacchetto, ma il pacchetto è stato installato da un'altra app, il sistema richiede la conferma dell'utente. In questo scenario, le app devono aspettarsiSTATUS_PENDING_USER_ACTION
come stato di ritorno 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 ricavare le chiavi (in modo non sicuro), perché questo provider non è più disponibile. Per maggiori informazioni, consulta il post del blog Provider "Crypto" di sicurezza deprecato in Android N.