A partire da Android 9 (livello API 28), la piattaforma limita le interfacce non SDK che la tua app può utilizzare. Queste limitazioni si applicano ogni volta che un'app fa riferimento a un'interfaccia non SDK o tenta di ottenerne l'handle utilizzando Floodlight o JNI. Queste limitazioni sono state messe in atto per contribuire a migliorare l'esperienza di utenti e sviluppatori e ridurre i rischi di arresti anomali per gli utenti e di implementazioni di emergenza per gli sviluppatori. Per saperne di più su questa decisione, consulta l'articolo Migliorare la stabilità riducendo l'utilizzo di interfacce non SDK.
Distinguere tra interfacce SDK e non SDK
In linea di massima, le interfacce SDK pubbliche sono quelle indicate nel framework Android Package Index. La gestione delle interfacce non SDK è un dettaglio di implementazione che l'API estrae, pertanto queste interfacce sono soggette a modifiche senza preavviso.
Per evitare arresti anomali e comportamenti imprevisti, le app devono utilizzare solo le parti delle classi ufficialmente documentate nell'SDK. Ciò significa anche che non devi accedere a metodi o campi non elencati nell'SDK quando interagisci con una classe utilizzando meccanismi come riflettere.
Elenchi di API non SDK
A ogni release di Android vengono applicate limitazioni aggiuntive per le interfacce non SDK. Siamo consapevoli che queste limitazioni possono influire sul flusso di lavoro della release e vogliamo assicurarci che tu disponga degli strumenti per rilevare l'utilizzo di interfacce non SDK, dell'opportunità di inviarci feedback e del tempo per pianificare e adeguare le nuove norme.
Per ridurre al minimo l'impatto delle limitazioni non relative all'SDK sul flusso di lavoro di sviluppo, le interfacce non SDK sono suddivise in elenchi che ne definiscono la limitazione di utilizzo in base al livello API scelto come target. La seguente tabella descrive ciascuno di questi elenchi:
Elenco | Tag di codice | Descrizione |
---|---|---|
Lista bloccata |
|
Interfacce non SDK che non puoi utilizzare indipendentemente dal livello API target dell'app. Se la tua app tenta di accedere a una di queste interfacce, il sistema genera un errore. |
Bloccato in modo condizionale |
|
A partire da Android 9 (livello API 28), ogni livello API ha interfacce non SDK limitate quando un'app ha come target quel livello API. Questi elenchi sono etichettati in base al livello API massimo ( Se la tua app tenta di accedere a un'interfaccia limitata per il tuo livello API target, il sistema si comporta come se l'API fa parte della lista bloccata. |
Non supportato |
|
Interfacce non SDK senza restrizioni e utilizzabili dalla tua app. Tuttavia, tieni presente che queste interfacce non sono supportate e sono soggette a modifiche senza preavviso. Nelle future versioni di Android, queste interfacce verranno bloccate in modo condizionale in un elenco max-target-x . |
SDK |
|
Interfacce che possono essere utilizzate liberamente e che ora sono supportate come parte del framework Android documentato ufficialmente Package Index. |
API di test |
|
Interfacce utilizzate per i test del sistema interno, ad esempio API che facilitano i test tramite la Compatibility Test Suite (CTS). Le API di test non fanno parte dell'SDK. A partire da Android 11 (livello API 30), le API di test sono incluse nella lista bloccata, pertanto alle app non è consentito utilizzarle, indipendentemente dal livello API target. Tutte le API di test non sono supportate e sono soggette a modifiche senza preavviso, indipendentemente dal livello API della piattaforma. |
Anche se puoi utilizzare alcune interfacce non SDK (a seconda del livello API target della tua app), l'utilizzo di qualsiasi metodo o campo non SDK comporta sempre un rischio elevato di danneggiare l'app. Se la tua app si basa su interfacce non SDK, dovresti iniziare a pianificare una migrazione alle interfacce SDK o ad altre alternative. Se non riesci a trovare un'alternativa all'utilizzo di un'interfaccia non SDK per una funzionalità nella tua app, devi richiedere una nuova API pubblica.
Stabilire a quale elenco appartiene un'interfaccia
Gli elenchi di interfacce non SDK vengono creati come parte della piattaforma. Per informazioni su ciascuna release di Android, consulta le sezioni seguenti.
Android 15 (beta)
Per Android 15, puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
7aa0987aea4b25f5371b7e377c9f37375ada3b7e30465c0e2d910a5b646c10c1
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 15, consulta Aggiornamenti alle limitazioni relative alle interfacce non SDK in Android 15.
Android 14
Per Android 14 (livello API 34), puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 14, consulta Aggiornamenti alle limitazioni relative alle interfacce non SDK in Android 14.
Android 13
Per Android 13 (livello API 33), puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 13, incluse le alternative di API pubbliche suggerite per le API bloccate in modo condizionale in Android 13, consulta Aggiornamenti alle limitazioni relative alle interfacce non SDK in Android 13.
Android 12
Per Android 12 (livello API 31), puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 12, incluse le alternative di API pubbliche suggerite per le API bloccate in modo condizionale in Android 12, consulta l'articolo Elenco delle modifiche per Android 12.
Android 11
Per Android 11 (livello API 30), puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 11, incluse le alternative di API pubbliche suggerite per le API bloccate in modo condizionale in Android 11, consulta l'articolo Elenco delle modifiche per Android 11.
Android 10
Per Android 10 (livello API 29), puoi scaricare il seguente file che descrive tutte le interfacce non SDK e i relativi elenchi:
File: hiddenapi-flags.csv
Checksum SHA-256:
f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb
Per scoprire di più sulle modifiche all'elenco di API non SDK in Android 10, incluse le alternative di API pubbliche suggerite per le API bloccate in modo condizionale in Android 10, consulta l'articolo Elenco delle modifiche per Android 10.
Android 9
Per Android 9 (livello API 28), il seguente file di testo contiene l'elenco delle API non SDK non limitate (in greylist): hiddenapi-light-greylist.txt
.
La lista bloccata (blacklist
) e l'elenco di API bloccate in modo condizionale (lista grigio scuro) vengono derivati al momento della creazione.
Genera elenchi da AOSP
Quando lavori con AOSP, puoi generare un file hiddenapi-flags.csv
che contiene tutte le interfacce non SDK e i relativi elenchi. Per farlo, scarica l'origine AOSP ed esegui questo comando:
m out/soong/hiddenapi/hiddenapi-flags.csv
Potrai quindi trovare il file nella seguente posizione:
out/soong/hiddenapi/hiddenapi-flags.csv
Comportamento previsto quando si accede a interfacce non SDK limitate
La seguente tabella descrive il comportamento previsto se la tua app tenta di accedere a un'interfaccia non SDK che fa parte della lista bloccata.
Modalità di accesso | Risultato |
---|---|
Istruzione Dalvik che fa riferimento a un campo | Lancio di NoSuchFieldError |
Istruzione Dalvik che fa riferimento a un metodo | Lancio di NoSuchMethodError |
Riflessione usando Class.getDeclaredField() o Class.getField() |
Lancio di NoSuchFieldException |
Riflesso usando Class.getDeclaredMethod() , Class.getMethod() |
Lancio di NoSuchMethodException |
Riflesso usando Class.getDeclaredFields() , Class.getFields() |
Membri non SDK non presenti nei risultati |
Riflesso usando Class.getDeclaredMethods() , Class.getMethods() |
Membri non SDK non presenti nei risultati |
JNI utilizza env->GetFieldID() |
NULL restituiti, NoSuchFieldError generati |
JNI utilizza env->GetMethodID() |
NULL restituiti, NoSuchMethodError generati |
Testare l'app per interfacce non SDK
Esistono diversi metodi che puoi utilizzare per testare le interfacce non SDK nella tua app.
Esegui test con un'app di cui è possibile eseguire il debug
Puoi testare le interfacce non SDK creando ed eseguendo un'app di debug su un dispositivo o un emulatore con Android 9 (livello API 28) o versioni successive. Assicurati che il dispositivo o l'emulatore che stai utilizzando corrisponda al livello API target della tua app.
Durante l'esecuzione dei test sulla tua app, il sistema stampa un messaggio di log se la tua app accede a determinate interfacce non SDK. Puoi esaminare i messaggi di log dell'app per trovare i seguenti dettagli:
- La classe, il nome e il tipo che dichiarano (nel formato utilizzato dal runtime Android).
- Il mezzo di accesso: collegare, utilizzare la riflessione o utilizzare JNI.
- Elenco a cui appartiene l'interfaccia non SDK.
Puoi utilizzare adb logcat
per accedere a questi messaggi di log, che vengono visualizzati sotto il PID dell'app in esecuzione. Ad esempio, una voce nel log potrebbe essere il seguente:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
Esegui test con l'API StrictMode
Puoi anche testare le interfacce non SDK utilizzando l'API StrictMode
. Utilizza il metodo detectNonSdkApiUsage
per abilitare questa funzionalità. Dopo aver abilitato l'API StrictMode
, puoi ricevere un callback per ogni utilizzo di un'interfaccia non SDK utilizzando una penaltyListener
, in cui puoi implementare la gestione personalizzata. L'oggetto Violation
fornito nel callback deriva da
Throwable
e l'analisi dello stack inclusa fornisce il contesto dell'utilizzo.
Esegui test con lo strumento veridex
Sul tuo APK puoi anche eseguire lo strumento di analisi statica veridex. Lo strumento veridex esegue la scansione dell'intero codebase dell'APK, comprese eventuali librerie di terze parti, e segnala gli utilizzi di interfacce non SDK trovate.
Le limitazioni dello strumento veridex includono le seguenti:
- Non può rilevare le chiamate tramite JNI.
- Può rilevare solo un sottoinsieme di chiamate tramite riflessione.
- La sua analisi dei percorsi di codice inattivi è limitata ai controlli a livello di API.
- Può essere eseguito solo su macchine che supportano le istruzioni SSE4.2 e POPCNT.
Windows
I file binari nativi di Windows non vengono forniti, ma puoi eseguire lo strumento veridex su Windows eseguendo i file binari di Linux utilizzando il sottosistema Windows per Linux (WSL). Prima di seguire i passaggi descritti in questa sezione, installa WSL e scegli Ubuntu come distribuzione Linux.
Dopo aver installato Ubuntu, avvia un terminale Ubuntu e segui questi passaggi:
- Scarica lo strumento veridex dal repository predefinito del runtime Android.
- Estrai i contenuti del file
appcompat.tar.gz
. - Nella cartella estratta, individua il file
veridex-linux.zip
ed estrailo. Vai alla cartella non compressa ed esegui il comando seguente, dove
your-app.apk
è l'APK che vuoi testare:./appcompat.sh --dex-file=your-app.apk
macOS
Per eseguire lo strumento veridex su macOS, segui questi passaggi:
- Scarica lo strumento veridex dal repository predefinito del runtime Android.
- Estrai i contenuti del file
appcompat.tar.gz
. - Nella cartella estratta, individua il file
veridex-mac.zip
ed estrailo. Passa alla cartella non compressa ed esegui il comando seguente, dove
/path-from-root/your-app.apk
è il percorso dell'APK che vuoi testare, a partire dalla directory root del sistema:./appcompat.sh --dex-file=/path-from-root/your-app.apk
Linux
Per eseguire lo strumento veridex su Linux, procedi nel seguente modo:
- Scarica lo strumento veridex dal repository predefinito del runtime Android.
- Estrai i contenuti del file
appcompat.tar.gz
. - Nella cartella estratta, individua il file
veridex-linux.zip
ed estrailo. Vai alla cartella non compressa ed esegui il comando seguente, dove
your-app.apk
è l'APK che vuoi testare:./appcompat.sh --dex-file=your-app.apk
Esegui test con lo strumento lint di Android Studio
Ogni volta che crei la tua app in Android Studio, lo strumento lint controlla il codice per individuare potenziali problemi. Se la tua app utilizza interfacce non SDK, potresti visualizzare avvisi o errori di build, a seconda dell'elenco a cui appartengono queste interfacce.
Puoi anche eseguire lo strumento lint dalla riga di comando o eseguire ispezioni manualmente su un progetto, una cartella o un file specifico.
Eseguire test con Play Console
Quando la carichi in un canale di test in Play Console, l'app viene testata automaticamente per rilevare potenziali problemi e viene generato un report pre-lancio. Se la tua app utilizza interfacce non SDK, nel report pre-lancio viene visualizzato un errore o un avviso, a seconda dell'elenco a cui appartengono queste interfacce.
Per maggiori informazioni, consulta la sezione Compatibilità Android in Utilizzare i report pre-lancio per identificare i problemi.
Richiedere una nuova API pubblica
Se non riesci a trovare un'alternativa all'utilizzo di un'interfaccia non SDK per una funzionalità nella tua app, puoi richiedere una nuova API pubblica creando una richiesta di funzionalità nel nostro Issue Tracker.
Quando crei una richiesta di funzionalità, fornisci le seguenti informazioni:
- L'API non supportata che stai utilizzando, incluso il descrittore completo visualizzato nel messaggio logcat
Accessing hidden ...
. - Perché devi utilizzare queste API, compresi i dettagli sulla funzionalità di alto livello per cui è necessaria l'API, non solo i dettagli di basso livello.
- Perché eventuali API SDK pubbliche correlate non sono sufficienti per le tue finalità.
- Qualsiasi altra alternativa che hai provato e il motivo per cui non ha funzionato.
Quando fornisci questi dettagli nella richiesta di funzionalità, aumenti la probabilità che venga concessa una nuova API pubblica.
Altre domande
Questa sezione include alcune risposte ad altre domande poste più spesso dagli sviluppatori:
Domande di carattere generale
In che modo Google può assicurarsi di soddisfare le esigenze di tutte le app tramite lo strumento Issuetracker?
Abbiamo creato gli elenchi iniziali per Android 9 (livello API 28) tramite l'analisi statica delle app che è stata integrata utilizzando i seguenti metodi:
- test manuali delle principali app Google Play e non Google
- report interni
- raccolta automatica dei dati dagli utenti interni
- report di anteprima per gli sviluppatori
- un'ulteriore analisi statica progettata per includere in modo prudente un maggior numero di falsi positivi
Durante la valutazione degli elenchi per ogni nuova release, teniamo conto dell'utilizzo dell'API e del feedback degli sviluppatori tramite l'Issue Tracker.
Come faccio ad attivare l'accesso a interfacce non SDK?
Puoi attivare l'accesso a interfacce non SDK sui dispositivi di sviluppo utilizzando i comandi adb per modificare il criterio di applicazione dell'API. I comandi che usi variano a seconda del livello dell'API. Questi comandi non richiedono un dispositivo rooted.
- Android 10 (livello API 29) o versioni successive
Per abilitare l'accesso, usa il seguente ADB
comando:
adb shell settings put global hidden_api_policy 1
Per reimpostare le impostazioni predefinite del criterio di applicazione dell'API, utilizza il seguente comando:
adb shell settings delete global hidden_api_policy
- Android 9 (livello API 28)
Per abilitare l'accesso, utilizza i seguenti comandi adb:
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
Per reimpostare le impostazioni predefinite del criterio di applicazione dell'API, utilizza i comandi seguenti:
adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps
Nel criterio di applicazione dell'API puoi impostare il numero intero su uno dei seguenti valori:
- 0: disattiva il rilevamento di interfacce non SDK. L'uso di questa impostazione disabilita tutti i messaggi di log per l'utilizzo di un'interfaccia non SDK e ti impedisce di testare la tua app utilizzando l'API
StrictMode
. Questa impostazione non è consigliata. - 1: abilita l'accesso a tutte le interfacce non SDK, ma stampa i messaggi di log con avvisi per qualsiasi utilizzo di interfacce non SDK. Questa impostazione ti consente anche di testare l'app utilizzando l'API
StrictMode
. - 2: non consentire l'utilizzo di interfacce non SDK che appartengono alla lista bloccata o che sono bloccate condizionale per il tuo livello API target.
Domande sugli elenchi di interfacce non SDK
Dove posso trovare gli elenchi di API non SDK nell'immagine di sistema?
Sono codificati nei bit del flag di accesso al campo e al metodo nei file dex della piattaforma. Non esiste un file separato nell'immagine di sistema che contiene questi elenchi.
Gli elenchi di API non SDK sono uguali su dispositivi OEM diversi con le stesse versioni Android?
Gli OEM possono aggiungere le proprie interfacce alla lista bloccata (blacklist), ma non possono rimuovere le interfacce dagli elenchi di API AOSP non SDK. Il CDD impedisce queste modifiche e i test CTS assicurano che Android Runtime faccia rispettare l'elenco.
Domande sulla compatibilità delle app correlate
Esistono restrizioni sulle interfacce non NDK nel codice nativo?
L'SDK Android include interfacce Java. La piattaforma ha iniziato a limitare l'accesso a interfacce non NDK per il codice C/C++ nativo in Android 7 (livello API 26). Per ulteriori informazioni, consulta l'articolo Migliorare la stabilità con le limitazioni dei simboli C/C++ privati in Android N.
Esiste un piano per limitare la manipolazione dei file dex2oat o DEX?
Non abbiamo piani attivi per limitare l'accesso al file binario dex2oat, ma non intendiamo che il formato file DEX sia stabile o che sia un'interfaccia pubblica oltre le parti specificate pubblicamente nel formato eseguibile Dalvik. Ci riserviamo il diritto di modificare o eliminare dex2oat e le parti non specificate del formato DEX in qualsiasi momento. Tieni inoltre presente che i file derivati prodotti da dex2oat come ODEX (noto anche come OAT), VDEX e CDEX sono tutti formati non specificati.
Cosa succede se un SDK di terze parti fondamentale (ad esempio un offuscamento) non può evitare di utilizzare interfacce non SDK, ma si impegna a mantenere la compatibilità con le versioni future di Android? In questo caso Android può rinunciare ai propri requisiti di compatibilità?
Non prevediamo di rinunciare ai requisiti di compatibilità per i singoli SDK. Se uno sviluppatore di SDK può mantenere la compatibilità solo in base alle interfacce negli elenchi non supportati (precedentemente grigi), deve iniziare a pianificare una migrazione alle interfacce SDK o ad altre alternative e richiedere una nuova API pubblica ogni volta che non riesce a trovare un'alternativa all'utilizzo di un'interfaccia non SDK.
Le limitazioni relative alle interfacce non SDK si applicano a tutte le app, incluse quelle di sistema e proprietarie, non solo alle app di terze parti?
Sì, tuttavia, sono esenti le app firmate con la chiave della piattaforma e alcune app di immagini di sistema. Tieni presente che queste esenzioni si applicano solo alle app che fanno parte dell'immagine di sistema (o delle app di immagini di sistema aggiornate). L'elenco è destinato esclusivamente alle app che vengono create
sulla base delle API delle piattaforme private, anziché delle API SDK (dove
LOCAL_PRIVATE_PLATFORM_APIS := true
).