Oltre a nuove funzionalità e capacità, Android 7.0 include una serie di modifiche al comportamento del sistema e delle API. Questo documento evidenzia alcune delle modifiche principali che devi comprendere e tenere conto nelle tue app.
Se hai già pubblicato un'app per Android, tieni presente che la tua app potrebbe essere interessata da queste modifiche alla piattaforma.
Batteria e memoria
Android 7.0 include modifiche al comportamento del sistema volte a migliorare la durata della batteria e a ridurre l'utilizzo della RAM. Queste modifiche possono influire sull'accesso della tua app alle risorse di sistema, nonché sul modo in cui interagisce con altre app tramite determinati intent impliciti.
Sospensione
Introdotta in Android 6.0 (livello API 23), la modalità Sospensione migliora la durata della batteria posticipando le attività della CPU e della rete quando un utente lascia un dispositivo scollegato, fermo e con lo schermo spento. Android 7.0 apporta ulteriori miglioramenti alla modalità Sospensione applicando un sottoinsieme di limitazioni della CPU e della rete quando il dispositivo è scollegato con lo schermo spento, ma non necessariamente fermo, ad esempio quando lo smartphone è in movimento nella tasca di un utente.
Quando un dispositivo è alimentato a batteria e lo schermo è stato spento per un determinato periodo di tempo, il dispositivo attiva la modalità Sospensione e applica il primo sottoinsieme di limitazioni: interrompe l'accesso alla rete delle app, rinvia i job e la sincronizzazione. Se il dispositivo rimane fermo per un determinato periodo di tempo dopo aver attivato la modalità Sospensione, il sistema applica il resto delle limitazioni della modalità Sospensione a PowerManager.WakeLock
, AlarmManager
, all'allarme, al GPS e alle ricerche Wi-Fi. Indipendentemente dal fatto che vengano applicate alcune o tutte le limitazioni di Sospensione, il sistema riattiva il dispositivo per brevi finestre di manutenzione, durante le quali le applicazioni sono autorizzate ad accedere alla rete e possono eseguire eventuali attività/sincronizzazioni differite.
Tieni presente che l'attivazione dello schermo o il collegamento del dispositivo fa uscire da Sospensione erimuove queste limitazioni di elaborazione. Il comportamento aggiuntivo non influisce sui suggerimenti e sulle best practice relativi all'adattamento della tua app alla versione precedente di Sospensione introdotta in Android 6.0 (livello API 23), come discusso in Ottimizzare per sospensione e standby delle app. Ti consigliamo comunque di seguire questi consigli, ad esempio di utilizzare Firebase Cloud Messaging (FCM) per inviare e ricevere messaggi, e di iniziare a pianificare gli aggiornamenti per supportare il comportamento aggiuntivo di Sospensione.
Project Svelte: ottimizzazioni in background
Android 7.0 rimuove tre trasmissioni implicite per contribuire a ottimizzare sia l'utilizzo della memoria sia il consumo di energia. Questa modifica è necessaria perché le trasmissioni implicite avviano spesso le app che si sono registrate per ascoltarle in background. La rimozione di queste trasmissioni può migliorare notevolmente le prestazioni del dispositivo e l'esperienza utente.
I dispositivi mobili subiscono frequenti cambiamenti di connettività, ad esempio durante il passaggio tra Wi-Fi e dati mobili. Al momento, le app possono monitorare le modifiche alla connettività registrando un ricevitore per la trasmissione implicita di CONNECTIVITY_ACTION
nel loro manifest. Poiché molte app si registrano per ricevere questa trasmissione, un singolo switch di rete può attivarle tutte ed elaborare la trasmissione contemporaneamente.
Allo stesso modo, nelle versioni precedenti di Android, le app potevano registrarsi per ricevere trasmissioni implicite di ACTION_NEW_PICTURE
e ACTION_NEW_VIDEO
da altre app, ad esempio Fotocamera. Quando un utente scatta una foto con l'app Fotocamera, queste app si riattivano per elaborare la trasmissione.
Per ovviare a 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 broadcasting
CONNECTIVITY_ACTION
se dichiarano il proprio ricevitore di trasmissione nel file manifest. Le app continueranno a ricevere le trasmissioniCONNECTIVITY_ACTION
se registrano il proprioBroadcastReceiver
conContext.registerReceiver()
e il contesto è ancora valido. - Il sistema non invia più trasmissioni
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 al più presto in modo da poter scegliere come target i dispositivi Android 7.0.
Il framework Android fornisce diverse soluzioni per ridurre la necessità di queste trasmissioni implicite. Ad esempio, l'API JobScheduler
fornisce un meccanismo efficace per pianificare le operazioni di rete quando vengono soddisfatte condizioni specifiche, come la connessione a una rete senza misurazione. Puoi anche utilizzare JobScheduler
per reagire alle modifiche apportate ai fornitori di contenuti.
Per maggiori informazioni sulle ottimizzazioni in background in Android 7.0 (livello API 24) e su come adattare la tua app, vedi 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 accesso limitato (0700
). Questa impostazione impedisce la perdita di metadati dei file privati, come le dimensioni o l'esistenza. Questa modifica dell'autorizzazione ha diversi effetti collaterali:
-
Le autorizzazioni dei file privati non devono più essere allentate dal proprietario
e un tentativo di farlo utilizzando
MODE_WORLD_READABLE
e/oMODE_WORLD_WRITEABLE
attiverà unSecurityException
.Nota:al momento, questa limitazione non è completamente applicata. Le app possono comunque modificare le autorizzazioni per la loro directory privata utilizzando API native o l'API
File
. Tuttavia, sconsigliamo vivamente di allentare le autorizzazioni per la directory privata. -
Se passi URI
file://
esterni al dominio del pacchetto, il destinatario potrebbe non avere accesso al percorso. Di conseguenza, i tentativi di passare un URIfile://
attivano unFileUriExposedException
. Il modo consigliato per condividere i contenuti di un file privato è utilizzareFileProvider
. -
DownloadManager
non può più condividere file archiviati privatamente in base al nome. Le applicazioni precedenti potrebbero avere un percorso non accessibile quando accedono aCOLUMN_LOCAL_FILENAME
. Le app che hanno come target Android 7.0 o versioni successive attivano unSecurityException
quando tentano di accedere aCOLUMN_LOCAL_FILENAME
. Le applicazioni precedenti che impostano la posizione di download su una posizione pubblica utilizzandoDownloadManager.Request.setDestinationInExternalFilesDir()
oDownloadManager.Request.setDestinationInExternalPublicDir()
possono comunque accedere al percorso inCOLUMN_LOCAL_FILENAME
, tuttavia questo metodo è vivamente sconsigliato. Il modo migliore per accedere a un file esposto dalDownloadManager
è tramiteContentResolver.openFileDescriptor()
.
Condivisione di file tra app
Per le app che hanno come target Android 7.0, il framework Android applica
le norme dell'API StrictMode
che vietano di esporre URI file://
al di fuori dell'app. Se un intent contenente un URI file esce dall'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 sull'URI. Il modo più semplice per concedere questa autorizzazione è
utilizzare la classe FileProvider
. Per ulteriori informazioni sulle autorizzazioni e sulla condivisione dei file, consulta Condivisione di file.
Accessibilità migliorata
Android 7.0 include modifiche volte a migliorare l'usabilità della piattaforma per gli utenti con vista ridotta o in difficoltà. In genere, queste modifiche non richiedono modifiche al codice dell'app, ma ti consigliamo di esaminarle e testarle con la tua app per valutare i potenziali impatti sull'esperienza utente.
Zoom schermo
Android 7.0 consente agli utenti di impostare le Dimensioni di visualizzazione, che ingrandiscono o riducono tutti gli elementi sullo schermo, migliorando così l'accessibilità del dispositivo per gli utenti ipovedenti. Gli utenti non possono aumentare lo zoom oltre una larghezza minima dello schermo di sw320dp, ovvero la larghezza di un Nexus 4, uno smartphone di medie dimensioni comune.
Quando la densità del dispositivo cambia, il sistema invia una notifica alle app in esecuzione nei modi seguenti:
- 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 di visualizzazione, il sistema termina l'app come se fosse in una situazione di memoria insufficiente. Se l'app ha processi in primo piano, il sistema li informa della modifica della configurazione come descritto in Gestione delle modifiche di runtime, proprio come se l'orientamento del dispositivo fosse cambiato.
- Se un'app ha come target Android 7.0, a tutti i suoi processi (in primo piano e in background) viene inviata una notifica della modifica di configurazione come descritto in Gestione delle modifiche di runtime.
La maggior parte delle app non deve apportare alcuna modifica per supportare questa funzionalità, a condizione che rispettino le best practice per Android. Aspetti specifici da controllare:
- Testa la tua app su un dispositivo con larghezza dello schermo
sw320dp
e assicurati che funzioni adeguatamente. - Quando la configurazione del dispositivo cambia, aggiorna le informazioni memorizzate nella cache che dipendono dalla densità, ad esempio bitmap o risorse caricate dalla rete. Controlla se ci sono modifiche alla configurazione quando l'app riprende dall' stato di pausa.
Nota:se memorizzi nella cache i dati dipendenti dalla configurazione, è consigliabile includere metadati pertinenti, come le dimensioni dello schermo o la densità di pixel appropriate per i dati. Il salvataggio di questi metadati ti consente di decidere se devi aggiornare i dati memorizzati nella cache dopo una modifica della configurazione.
- Evita di specificare le dimensioni con unità px, poiché non si adattano alla densità dello schermo. Specifica invece le dimensioni con unità di pixel indipendenti dalla densità (
dp
).
Impostazioni di visione artificiale nella configurazione guidata
Android 7.0 include le impostazioni di visione nella schermata di benvenuto, dove gli utenti possono configurare le seguenti impostazioni di accessibilità su un nuovo dispositivo: Gesto di zoom, Dimensione carattere, Dimensione 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 di app NDK alle librerie della piattaforma
A partire da Android 7.0, il sistema impedisce alle app di collegarsi dinamicamente a librerie non NDK, causando l'arresto anomalo dell'app. Lo scopo di questo cambiamento di comportamento è creare un'esperienza coerente dell'app negli aggiornamenti della piattaforma e su dispositivi diversi. Anche se il codice potrebbe non eseguire il collegamento con librerie private, è possibile che una libreria statica di terze parti nell'app lo faccia. Pertanto, tutti gli sviluppatori devono verificare che le loro app non si arrestino in modo anomalo sui dispositivi con Android 7.0. Se la tua app utilizza codice nativo, devi utilizzare solo le API NDK pubbliche.
Esistono tre modi in cui la tua app potrebbe tentare di accedere alle API della piattaforma privata:
- L'app accede direttamente alle librerie della piattaforma private. 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 raccolta di terze parti che accede alle librerie della piattaforma private. Anche se hai la certezza che la tua app non acceda direttamente alle librerie private, devi comunque testarla per questo scenario.
- La tua app fa riferimento a una libreria non inclusa nel suo APK. Ad esempio, questo potrebbe accadere se hai provato a utilizzare la tua copia di OpenSSL, ma hai dimenticato di aggregarla all'APK della tua app. L'app potrebbe funzionare normalmente sulle versioni della piattaforma Android che includono
libcrypto.so
. Tuttavia, l'app potrebbe arrestarsi in modo anomalo su 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 l'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 questo tipo di modifica. Inoltre, poiché non esistono requisiti di compatibilità per le librerie di piattaforma non incluse nell'NDK, dispositivi diversi potrebbero offrire livelli diversi di compatibilità.
Per ridurre l'impatto che questa limitazione potrebbe avere sulle app attualmente
rilasciate, un insieme di librerie che registra un utilizzo significativo, ad esempio
libandroid_runtime.so
, libcutils.so
,
libcrypto.so
e libssl.so
, è temporaneamente
accessibile 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 messaggio popup per informarti. 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 del tutto 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 è pubblica né temporaneamente accessibile. Il risultato è che
System.loadLibrary
e dlopen(3)
restituiscono entrambi
NULL
e potrebbero causare l'arresto anomalo dell'app. Ti consigliamo di esaminare il codice dell'app per rimuovere l'utilizzo delle API di piattaforma private e di testare attentamente le 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 tabella seguente descrive il comportamento che dovresti aspettarti da un'app in base all'utilizzo delle librerie native private e al livello API target (android:targetSdkVersion
).
Biblioteche | Livello API target | Accesso in fase di esecuzione tramite linker dinamico | Comportamento di Android 7.0 (livello API 24) | Comportamento futuro della piattaforma Android |
---|---|---|---|---|
NDK Public | Qualche | Accessibilità | Funziona come previsto | Funziona come previsto |
Privato (librerie private accessibili temporaneamente) | 23 o meno | Temporaneamente accessibile | Funziona come previsto, ma ricevi un avviso logcat. | Errore di runtime |
Privato (librerie private accessibili temporaneamente) | 24 o successiva | Con restrizioni | Errore di runtime | Errore di runtime |
Privato (altro) | Qualche | 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 inferiore 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 di logcat indicano quale libreria sta tentando di accedere a un'API della piattaforma privata, ma non causeranno 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 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 vedere questi output di logcat anche se la tua app utilizza librerie di terze parti
che si collegano dinamicamente alle API della piattaforma privata. Lo strumento readelf nell'Android 7.0DK consente di generare un elenco di tutte le librerie condivise con link dinamico di un determinato file .so
eseguendo il seguente 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 la tua app non abbia arresti anomali nei futuri aggiornamenti della piattaforma:
- Se la tua app utilizza librerie di piattaforme private, devi aggiornarla in modo da includere la propria copia 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 aggiornarla.
- Assicurati di pacchettizzare tutte le librerie non NDK con il tuo APK.
- Utilizza 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>.
- Utilizza
__system_property_get
anziché il simbolo privatoproperty_get
dilibcutils.so
. Per farlo, utilizza__system_property_get
con la seguente inclusione:#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 del tutto queste proprietà.
- Utilizza una versione locale del simbolo
SSL_ctrl
dilibcrypto.so
. Ad esempio, devi collegare in modo staticolibcyrpto.a
nel file.so
o includere una versione collegata in modo dinamico dilibcrypto.so
da BoringSSL/OpenSSL e pacchettizzarla nel tuo APK.
Android for Work
Android 7.0 contiene modifiche per le app che hanno come target Android for Work, tra cui modifiche all'installazione dei certificati, alla reimpostazione della password, alla gestione degli utenti secondari e all'accesso agli identificatori dei dispositivi. Se stai creando app per ambienti Android for Work, devi esaminare queste modifiche e modificare la tua app di conseguenza.
- Devi installare un installatore di certificati delegati prima che il PDC 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 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 messaggio di erroreIllegalArgumentException
. - Le limitazioni di reimpostazione della password per gli amministratori dei dispositivi ora si applicano ai proprietari del profilo. Gli amministratori dei dispositivi non possono più utilizzare
DevicePolicyManager.resetPassword()
per cancellare le password o modificarne 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 limitazioni. I proprietari di dispositivi e di profili possono chiamare le API di gestione dell'account anche se sono in vigore limitazioni per gli utenti
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. In questo modo gli utenti non possono creare utenti secondari non gestiti. Inoltre, i metodiCreateUser()
ecreateAndInitializeUser()
sono deprecati e sostituiti dal nuovoDevicePolicyManager.createAndManageUser()
. - I proprietari dei dispositivi possono accedere agli identificatori dei dispositivi. Un proprietario del 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à Lavoro è disattivata, il programma di avvio del sistema indica che le app di lavoro non sono disponibili impostandole su grigio. La re-attivazione 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 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 del cliente in un secondo momento. Se necessario, il certificato CA deve essere installato separatamente nello spazio di archiviazione delle credenziali attendibili tramite l'interfaccia utente Impostazioni, con un formato con codifica DER e un'estensione file .crt o .cer. - A partire da Android 7.0, la registrazione e l'archiviazione delle impronte vengono gestite per utente. Se il client Device Policy (DPC) 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. Quando il DPC ha come target il livello API 24 e versioni successive, l'utente può impostare l'impronta specificamente 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
per indicare che la crittografia è attiva e che la chiave di crittografia è associata all'utente. Il nuovo stato viene restituito solo se il DPC ha come target il livello API 24 e versioni successive. 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 normalmente influiscono sull'intero
dispositivo si comportano in modo diverso se sul dispositivo è installato un
profilo di lavoro con una verifica di lavoro separata. Invece di influire sull'intero dispositivo, questi metodi si applicano solo al profilo di lavoro. L'elenco completo di questi metodi è riportato nella documentazione di
DevicePolicyManager.getParentProfileInstance()
. Ad esempio,DevicePolicyManager.lockNow()
blocca solo il profilo di lavoro, anziché bloccare l'intero dispositivo. Per ciascuno di questi metodi, puoi ottenere il vecchio comportamento chiamando il metodo sull'istanza principale diDevicePolicyManager
. Puoi ottenere questo elemento principale chiamandoDevicePolicyManager.getParentProfileInstance()
. Ad esempio, se chiami il metodolockNow()
dell'istanza principale, l'intero dispositivo viene bloccato.
Conservazione delle annotazioni
Android 7.0 corregge un bug per cui la visibilità delle annotazioni veniva ignorata. Questo problema consentiva al runtime di accedere ad annotazioni a cui non avrebbe dovuto essere in grado di accedere. Queste annotazioni includevano:
VISIBILITY_BUILD
: destinato a essere visibile solo al momento della build.VISIBILITY_SYSTEM
: deve essere visibile in fase di runtime, ma solo per il sistema di base.
Se la tua app si basa su questo comportamento, aggiungi un criterio di conservazione alle annotazioni che devono essere disponibili in fase di esecuzione. Per farlo, utilizzi @Retention(RetentionPolicy.RUNTIME)
.
Modifiche alla configurazione predefinita di TLS/SSL
Android 7.0 apporta le seguenti modifiche alla configurazione TLS/SSL predefinita utilizzata dalle app per il traffico HTTPS e 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 può causare interruzioni nella connettività HTTPS o TLS/SSL se il server non negozia suite di crittografia moderne. La soluzione preferita è migliorare la configurazione del server per attivare protocolli e suite di crittografia più efficaci e moderni. Idealmente, TLSv1.2 e AES-GCM dovrebbero essere abilitati e le suite di crittografia Forward Secrecy (ECDHE) dovrebbero essere abilitate e preferite.
Un'alternativa è modificare l'app in modo da utilizzare un SSLSocketFactory
personalizzato per comunicare con il server. La factory deve essere progettata per creare istanze SSLSocket
con alcune delle suite di crittografia richieste dal server attivate, 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 che hanno come target Android 7.0 (livello API 24) o versioni successive. Le app compilate per Android 7.0 o che impostano targetSdkVersion
su Android 7.0 o versioni successive devono modificare le proprie app per supportare correttamente questi comportamenti, se applicabili all'app.
Modifiche alla serializzazione
In Android 7.0 (livello API 24) è stato corretto un bug nel calcolo del valore serialVersionUID predefinito, che non corrispondeva alla specifica.
Le classi che implementano Serializable
e non specificano un campo serialVersionUID
esplicito potrebbero subire una modifica del serialVersionUID predefinito, che causerebbe un'eccezione al tentativo di deserializzare le istanze della classe che sono state serializzate in 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
del messaggio di errore, ad esempio 1234
in questo caso. Questa modifica è conforme a tutte le best practice per la scrittura di codice di serializzazione e funzionerà su tutte le versioni di Android.
Il bug specifico che è stato corretto riguardava la presenza di metodi di inizializzazione statici, ovvero <clinit>
. In base alla
specifica, la presenza o l'assenza di un metodo di inizializzatore statico nella
classe influisce sul serialVersionUID predefinito calcolato per quella classe.
Prima della correzione del bug, il calcolo controllava anche la superclasse per verificare la presenza di un inizializzatore statico, se una classe non ne aveva uno.
Per chiarire, questa modifica non riguarda le app che hanno come target livelli API 23 o
inferiori, le classi con un campo serialVersionUID
o le classi con
un metodo di inizializzazione statico.
Altri punti importanti
- Quando un'app è in esecuzione su Android 7.0, ma ha come target un livello API inferiore,
e l'utente modifica le dimensioni del display, il processo dell'app viene interrotto. L'app
deve essere in grado di gestire agevolmente questo scenario. In caso contrario, si arresta in modo anomalo quando l'utente lo ripristina da Recenti.
Dovresti testare l'app per assicurarti che non si verifichi questo comportamento. Per farlo, puoi causare un arresto anomalo identico durante l'interruzione manuale dell'app tramite DCM.
Le app che hanno come target Android 7.0 (livello API 24) e versioni successive non vengono terminate automaticamente in caso di modifiche alla densità. Tuttavia, potrebbero comunque rispondere male alle modifiche alla configurazione.
- Le app su Android 7.0 dovrebbero essere in grado di gestire in modo corretto le modifiche alla configurazione e non dovrebbero arrestarsi in modo anomalo agli avvii successivi. Puoi verificare il comportamento dell'app modificando la dimensione del carattere (Impostazioni > Display > Dimensione carattere) e poi ripristinando l'app da Recenti.
-
A causa di un bug nelle versioni precedenti di Android, il sistema non segnalava la scrittura
in una socket TCP sul thread principale come violazione del modo rigoroso. Questo bug è stato corretto in Android 7.0.
Le app che mostrano questo comportamento ora generano un
android.os.NetworkOnMainThreadException
. In genere, non è consigliabile eseguire operazioni di rete sul thread principale perché queste operazioni solitamente hanno una latenza elevata che causa ANR e scatti. -
Per impostazione predefinita, la famiglia di metodi
Debug.startMethodTracing()
ora memorizza l'output nella directory specifica del pacchetto sullo spazio di archiviazione condiviso, anziché a livello superiore della scheda SD. Ciò significa che le app non devono più richiedere l'autorizzazioneWRITE_EXTERNAL_STORAGE
per utilizzare queste API. -
Molte API di piattaforma ora hanno iniziato a verificare la presenza di payload di grandi dimensioni inviati
tra le transazioni
Binder
e il sistema ora reimpostaTransactionTooLargeExceptions
comeRuntimeExceptions
, anziché registrarli o eliminarli silenziosamente. Un esempio comune è l'archiviazione di troppi dati inActivity.onSaveInstanceState()
, che causa l'emissione di un messaggio di errore da parte diActivityThread.StopInfo
RuntimeException
quando la tua app ha come target Android 7.0. -
Se un'app pubblica attività
Runnable
in unView
e ilView
non è associato a una finestra, il sistema mette in coda l'attivitàRunnable
con ilView
. L'attivitàRunnable
non viene eseguita finché ilView
non è associato a una finestra. Questo comportamento corregge i seguenti bug:- Se un'app ha pubblicato un messaggio in un
View
da un thread diverso da quello dell'interfaccia utente della finestra prevista, ilView
potrebbe essere eseguito sul thread sbagliato.Runnable
- Se l'attività
Runnable
è stata pubblicata da un thread diverso da un thread looper, l'app potrebbe esporre l'attivitàRunnable
.Runnable
- Se un'app ha pubblicato un messaggio in un
-
Se un'app su Android 7.0 con l'autorizzazione
DELETE_PACKAGES
tenta di eliminare un pacchetto, ma un'altra app lo ha installato, il sistema richiede la conferma dell'utente. In questo scenario, le app dovrebbero aspettarsiSTATUS_PENDING_USER_ACTION
come stato di ritorno quando invocanoPackageInstaller.uninstall()
. - Il provider JCA denominato Crypto è deprecato perché il suo unico algoritmo, SHA1PRNG, è debole dal punto di vista crittografico. Le app non possono più utilizzare SHA1PRNG per dedurre (in modo non sicuro) le chiavi, perché questo provider non è più disponibile. Per ulteriori informazioni, consulta il post del blog Provider "Crypto" di sicurezza ritirato in Android N.