Best practice per Android StrictMode

Un recente aggiornamento alla piattaforma Android ha aggiunto una nuova classe chiamata StrictMode (android.os.StrictMode). Questa classe può essere utilizzata per abilitare e applicare varie politiche che possono essere controllate e segnalate. Queste politiche generalmente includono problemi di codifica di tipo best-practice, come il monitoraggio delle azioni eseguite sul thread principale che non dovrebbero essere e altre pratiche di codifica maliziose o pigri.

StrictMode ha varie politiche. Ogni politica ha varie regole. Ogni politica ha anche vari metodi di mostrare quando una regola viene violata. Definiremo prima questi e poi daremo un rapido esempio di come vengono utilizzati.

Criteri, regole e penalità StrictMode

Attualmente, ci sono due categorie di politiche disponibili per l'uso. Uno è il criterio del thread e l'altro è il criterio VM (macchina virtuale, da non confondere con la memoria virtuale). La politica del thread può monitorare:

  • Lettura del disco
  • Disk Writes
  • Accesso alla rete
  • Codice lento personalizzato

I primi tre elementi di questo elenco sono relativamente auto-esplicativi nel modo in cui vengono attivati. Il quarto è attivato semplicemente da una chiamata che puoi fare alla classe. Faresti questo dal tuo codice che è noto per essere lento. Il rilevamento di violazioni delle policy avviene quando le chiamate vengono effettuate sul thread principale. Ad esempio, potresti attivare il? Codice lento? violazione ogni volta che l'applicazione scarica e analizza una grande quantità di dati.

La politica VM può monitorare i seguenti problemi:

  • Oggetti attività trapelati
  • Oggetti SQLite trapelati
  • Trapelato oggetti chiudibili

Mentre i primi due elementi sono auto esplicativi, il terzo è un po 'meno. Il controllore degli oggetti chiudibili trapelati controlla gli oggetti che devono essere chiusi, tramite una chiamata a close () o simili, prima che siano finalizzati.

Ogni politica ha anche una varietà di mezzi diversi per farti sapere quando una regola è stata violata. Le violazioni possono essere scritte su LogCat (utile per quegli esempi di codice lento), memorizzate nel servizio DropBox (android.os.DropBox), o in crash dell'applicazione. Inoltre, le violazioni dei criteri di thread possono far lampeggiare lo sfondo dello schermo o mostrare una finestra di dialogo. Tutti questi metodi possono essere utilizzati per aiutarti a azzerare e sradicare questi difetti applicativi.

Passaggio 1: attivazione di StrictMode

Per abilitare e configurare StrictMode nell'applicazione, è consigliabile utilizzare i metodi StrictMode di setThreadPolicy () e setVmPolicy () il più presto possibile nel ciclo di vita dell'applicazione. Quando si tratta della politica di Thread, quale Thread è lanciato anche in materia (controlla solo gli errori su quel thread, di solito il thread principale). Un buon posto per impostare le politiche è ai punti di ingresso per la vostra applicazione e attività. Ad esempio, in una semplice applicazione, potrebbe essere necessario inserire il codice nel metodo onCreate () della classe Attività di avvio.

Il seguente codice abilita tutte le regole su entrambe le politiche correnti. Una finestra di dialogo viene visualizzata ogni volta che viene violata una regola dei criteri Thread.

 StrictMode.setThreadPolicy (new StrictMode.ThreadPolicy.Builder () .detectAll () .penaltyLog () .penaltyDialog () .build ()); StrictMode.setVmPolicy (new StrictMode.VmPolicy.Builder (). DetectAll () .penaltyLog () .build ());

Non lasciare questo codice abilitato in un'applicazione di produzione. È progettato solo per l'uso in pre-produzione. Invece, un flag può essere utilizzato per attivare in modo condizionato StrictMode o disattivato.

Passaggio 2: esecuzione con StrictMode

Un'applicazione in StrictMode non si comporta in modo diverso dal normale. Basta eseguire l'applicazione e testare come faresti normalmente. L'esecuzione di uno script esauriente di test che esercita a fondo l'applicazione e tocca l'intera base di codice con StrictMode abilitato probabilmente ti fornirà i risultati più utili.

Ecco un esempio dell'output di LogCat quando eseguiamo una versione dell'applicazione TutList con StrictMode abilitato (tutte le policy, tutte le regole):

 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): violazione della politica StrictMode; ~ duration = 319 ms: android.os.StrictMode $ StrictModeDiskWriteViolation: policy = 31 violazione = 1 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.os.StrictMode $ AndroidBlockGuardPolicy.onWriteToDisk (StrictMode.java : 1041) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.database.sqlite.SQLiteStatement.acquireAndLock (SQLiteStatement.java:219) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883 ): su android.database.sqlite.SQLiteStatement.executeUpdateDelete (SQLiteStatement.java:83) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.database.sqlite.SQLiteDatabase.updateWithOnConflict (SQLiteDatabase.java: 1829) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.database.sqlite.SQLiteDatabase.update (SQLiteDatabase.java:1780) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883) : su com.mamlambo.tutorial.tutlist.data.TutListProvider.update (TutListProvider.java:188) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.content.ContentProvider $ Transport.update (ContentProvider .java: 233) 09-04 1 6: 15: 34.592: DEBUG / StrictMode (15883): su android.content.ContentResolver.update (ContentResolver.java:847) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su com.mamlambo.tutorial .tutlist.data.TutListProvider.markItemRead (TutListProvider.java:229) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): in com.mamlambo.tutorial.tutlist.TutListFragment.onListItemClick (TutListFragment.java:99) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.support.v4.app.ListFragment $ 2.onItemClick (ListFragment.java:53) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883 ): su android.widget.AdapterView.performItemClick (AdapterView.java:282) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.widget.AbsListView.performItemClick (AbsListView.java:1037) 09- 04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.widget.AbsListView $ PerformClick.run (AbsListView.java:2449) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su Android. widget.AbsListView $ 1.run (AbsListView.java:3073) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): a andro id.os.Handler.handleCallback (Handler.java:587) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.os.Handler.dispatchMessage (Handler.java:92) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.os.Looper.loop (Looper.java:132) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su android.app.ActivityThread.main (ActivityThread.java:4123) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): a java.lang.reflect.Method.invokeNative (metodo nativo) 09-04 16: 15: 34.592: DEBUG / StrictMode ( 15883): a java.lang.reflect.Method.invoke (Method.java:491) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): a com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:841) 09-04 16: 15: 34.592: DEBUG / StrictMode (15883): su com.android.internal.os.ZygoteInit.main (ZygoteInit.java:599) 09-04 16: 15: 34.592 : DEBUG / StrictMode (15883): su dalvik.system.NativeStart.main (metodo nativo)

Puoi vederlo da solo aggiungendo il codice StrictMode al codice di versione 13 di TutList. Basta selezionare un elemento diverso dalla lista.

Cosa ci dice questo registro? L'atto di semplicemente contrassegnare un messaggio come letto dovrebbe essere stato fatto fuori dal thread principale. Invece, sta mangiando un terzo di secondo! Non solo è sorprendentemente lento, ma l'effetto sull'interfaccia utente è evidente.

Ed ecco come appare la finestra di avviso:

Passaggio 3: ignorare alcune violazioni dei criteri

La maggior parte degli avvisi generati da StrictMode dovrebbero essere seguiti, ma non tutti gli avvisi generati indicano che qualcosa non va nel tuo codice. Ci sono molte situazioni in cui, ad esempio, si sa che una lettura veloce da disco sulla discussione principale non ostacolerà notevolmente l'applicazione. O forse hai qualche altro codice di debug che viola le regole che non saranno abilitate in una build di produzione.

Il primo modo per ignorare le violazioni delle norme è documentarle per te o il tuo team e elencarle come violazioni note. Il secondo modo è quello di aggiungere esplicitamente del codice per interrompere il controllo di una particolare violazione della regola appena prima dell'esecuzione del codice illecito e quindi riabilitare il rilevamento per quella regola dopo che il codice incriminato è stato completato. Per esempio:

 StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy (); StrictMode.setThreadPolicy (new StrictMode.ThreadPolicy.Builder (old) .permitDiskWrites () .build ()); doCorrectStuffThatWritesToDisk (); StrictMode.setThreadPolicy (vecchio);

Questo codice salva la politica corrente, crea una politica simile che ignora la violazione delle scritture su disco, esegue il codice che esegue alcune scritture su disco e ripristina la politica originale.

Conclusione

StrictMode è una classe utile nell'arsenale di strumenti diagnostici disponibili per gli sviluppatori Android. Attraverso di esso, gli sviluppatori possono trovare e risolvere problemi di prestazioni sottili, perdite di oggetti e altri problemi di runtime difficili da trovare. Stai usando StrictMode? Ci sono altre norme che vorresti vedere aggiunte a questa funzione di Android SDK?

Riguardo agli Autori

Gli sviluppatori mobili Lauren Darcey e Shane Conder hanno coautore diversi libri sullo sviluppo di Android: un libro di programmazione approfondito intitolato Sviluppo di applicazioni wireless Android, seconda edizione e Sams ti insegna a sviluppare applicazioni Android in 24 ore, seconda edizione. Quando non scrivono, passano il loro tempo a sviluppare software mobile presso la loro azienda ea fornire servizi di consulenza. Possono essere contattati via email a [email protected], tramite il loro blog su androidbook.blogspot.com e su Twitter @androidwireless.

Hai bisogno di più aiuto nella scrittura di app per Android? Consulta i nostri ultimi libri e risorse!

я я