Garantire il codice Android di alta qualità con gli strumenti di analisi statica

Nel tutorial di oggi, impareremo come garantire un codice Android di alta qualità nei nostri progetti utilizzando alcuni strumenti di analisi del codice statico per Java. Guarderemo Checkstyle, FindBugs, PMD e Android Studio Lint, tutti gratuiti e open source!

Cosa sono gli strumenti di analisi del codice statico?

Questi sono strumenti che analizzano e analizzano il codice sorgente senza eseguirlo. L'obiettivo è trovare potenziali vulnerabilità come bug e difetti di sicurezza. Un popolare analizzatore gratuito di codici statici come FindBugs controlla il tuo codice rispetto a un insieme di regole a cui il tuo codice dovrebbe attenersi, se il codice non segue queste regole, è un segno che qualcosa potrebbe essere sbagliato. Pensa agli strumenti di analisi del codice statico come un compilatore aggiuntivo che viene eseguito prima della compilazione finale nella lingua del sistema.  

Molte società di software richiedono che i progetti superino i test di analisi del codice statico, oltre a eseguire revisioni del codice e test unitari nel processo di compilazione. Anche i manutentori di progetti open source spesso includono uno o più passaggi di analisi del codice statico nel processo di compilazione. Quindi, l'apprendimento dell'analisi statica è un passo importante nella scrittura del codice di qualità. Essere consapevoli del fatto che l'analisi del codice statico, nota anche come test "white-box", non deve essere vista come una sostituzione per il test dell'unità del codice sorgente.

In questo tutorial, apprenderemo alcuni strumenti di analisi statica più diffusi disponibili per Android e Java. Ma prima, vediamo alcuni dei vantaggi dell'utilizzo dell'analisi statica.

Benefici

  • Aiuta a rilevare potenziali bug che potrebbero essere sfuggiti anche a unità o test manuali.
  • Definisce regole specifiche del progetto. Ad esempio, l'analisi statica come parte della catena di costruzione aiuta i nuovi arrivati ​​a raggiungere la velocità con gli standard di codice del loro nuovo team.
  • Ti aiuta a migliorare la tua conoscenza di una nuova lingua.
  • Esegue la scansione dell'intero progetto, inclusi i file che potresti non aver mai letto.

Impostare

Tutti gli strumenti di analisi del codice che apprenderemo in questo tutorial sono disponibili come plugin Gradle, quindi possiamo creare singoli compiti Gradle per ognuno di essi. Usiamo un singolo file Gradle che includerà tutti loro. Ma prima, creiamo una cartella che conterrà tutti i nostri file per l'analisi del codice statico. 

Apri Android Studio e all'interno del modulo dell'app (in Progetto vista), creare una nuova cartella e nominarla code_quality_tools. Questa cartella conterrà i file XML per gli strumenti di analisi del codice e avrà anche un file Gradle, quality.gradle, che eseguirà le nostre attività di analisi statica. 

Infine, visita il tuo build.gradle nella cartella del modulo dell'app e includere questa riga alla fine del file:

applicare da: '/code_quality_tools/quality.gradle'

Qui, il nostro qualità.Gradle Lo script Gradle viene applicato con un riferimento alla posizione del file locale. 

Checkstyle

Date le regole specificate in un file XML per applicare uno standard di codifica per il progetto, Checkstyle applica tali regole analizzando il codice sorgente e confrontandole con standard o convenzioni di codifica noti. 

Checkstyle è uno strumento open source mantenuto attivamente dalla comunità. Ciò significa che è possibile creare assegni personalizzati o modificare quelli esistenti in base alle proprie esigenze. Ad esempio, Checkstyle può eseguire un controllo sui nomi delle costanti (finale, statico o entrambi) nelle classi. Se i tuoi nomi costanti non si attengono a una regola di essere in maiuscolo con parole separate da un trattino basso, il problema verrà contrassegnato nel rapporto finale. 

// stringa statica finale privata errata myConstant = "myConstant"; // corregge la stringa statica finale privata MY_CONSTANT = "myConstant";

Integrazione di Checkstyle

Ti mostrerò come integrare Checkstyle nel nostro progetto Android Studio e dimostrare un esempio pratico.

Innanzitutto, dobbiamo creare le nostre regole di codifica. Dentro checkstyle.xml, creiamo alcune regole di configurazione di Checkstyle che verranno eseguite contro il nostro codice.

                  

Nel codice precedente, includiamo le regole o i controlli che vogliamo che Checkstyle convalidi nel nostro codice sorgente. Una regola è AvoidStarImport che, come dice il nome, controlla se il codice sorgente includesse una dichiarazione di importazione come java.util. *. (Invece, dovresti specificare esplicitamente il pacchetto da importare, ad es. java.util.Observable.) 

Alcune regole hanno proprietà, che possiamo impostare proprio come abbiamo fatto per ParameterNumber: questo limita il numero di parametri di un metodo o costruttore. Di default, la proprietà max è 7, ma abbiamo cambiato invece a 6. Dai un'occhiata ad altri controlli sul sito web di Checkstyle.

Per eseguire questo controllo, dobbiamo creare un'attività Gradle. Quindi visita il quality.gradle file e creare un'attività chiamata checkstyle:

applica il plugin: checkstyle del task 'checkstyle' (type: Checkstyle) descrizione 'Controlla il file standard' group 'verifica' configFile file ('./ code_quality_tools / checkstyle.xml') source 'src' include '** / *. java' escludi '** / gen / **' classpath = files () ignoreFailures = false

Nota che nel codice qui sopra abbiamo prima applicato il plug-in Checkstyle Gradle. Gli abbiamo fornito una descrizione e l'abbiamo aggiunta a un gruppo Gradle già definito chiamato verifica. 

Le proprietà chiave dell'attività di Checkstyle Gradle di cui ci occupiamo sono: 

  • configFile: il file di configurazione di Checkstyle da utilizzare.
  • IgnoreFailures: se consentire o meno alla generazione di continuare se ci sono avvertimenti.
  • includere: il set di pattern di inclusione.
  • escludere: il set di pattern di esclusione. In questo caso, non analizziamo le classi generate. 

Infine, puoi eseguire lo script Gradle visitando la finestra dello strumento Gradle su Android Studio, aprendo il verifica gruppo, quindi facendo clic su checkstyle per eseguire l'operazione. 

Un altro modo è usare la riga di comando: 

gradle checkstyle

Al termine dell'esecuzione dell'attività, verrà generato un rapporto, disponibile all'indirizzo modulo app> build> rapporti> checkstyle. Puoi aprire checkstyle.html per visualizzare il report. 

Un plug-in Checkstyle è disponibile gratuitamente per Android Studio o IntelliJ IDEA. Offre la scansione in tempo reale dei tuoi file Java. 

PMD

PMD è un altro strumento di analisi del codice open source che analizza il tuo codice sorgente. Trova difetti comuni come variabili inutilizzate, blocchi di catch vuoti, creazione di oggetti non necessari e così via. PMD ha molte regole da cui puoi scegliere. Un esempio di una regola che fa parte del set di regole di progettazione è:

  • SimplifyBooleanExpressions: evitare confronti non necessari nelle espressioni booleane che complicano il codice semplice. Un esempio: 
la barra della classe pubblica // può essere semplificata in // bar = isFoo (); private boolean bar = (isFoo () == true); public isFoo () return false;

PMD è configurato con PMD.xml file. Al suo interno, includeremo alcune regole di configurazione come quelle per Android, Naming e Design. 

  Set di regole personalizzate per l'applicazione Android .* / R.java .* / Gen /.*                 

Come abbiamo fatto per Checkstyle, abbiamo anche bisogno di creare un'attività PMD Gradle per il controllo da eseguire all'interno di quality.gradle file. 

applica plugin: task pmd pmd (tipo: Pmd) descrizione 'Esegui PMD' gruppo 'verifica' regolaSetFiles = file ("./ code_quality_tools / pmd.xml") source 'src' include '** / *. java' escludi i rapporti '** / gen / **' xml.enabled = false html.enabled = true ignoreFailures = false

PMD è anche disponibile come plugin Gradle. 

Le proprietà chiave dell'attività che abbiamo creato sono: 

  • ruleSetFiles: I file di set di regole personalizzati da utilizzare.
  • fonte: La fonte per questa attività.
  • rapporti: I report da generare da questa attività.

Infine, puoi eseguire lo script Gradle visitando la finestra dello strumento Gradle, aprendo la cartella del gruppo di verifica e quindi facendo clic su PMD per eseguire l'operazione. Oppure puoi eseguirlo tramite la riga di comando:

gradle pmd

Un rapporto verrà generato anche dopo l'esecuzione dell'attività che è disponibile all'indirizzo modulo app> build> rapporti> pmd. C'è anche un plugin PMD disponibile per IntelliJ o Android Studio che puoi scaricare e integrare se vuoi. 

FindBugs

FindBugs è un altro strumento gratuito di analisi statica che analizza la tua classe alla ricerca di potenziali problemi controllando i tuoi bytecode rispetto a un elenco noto di schemi di errore. Alcuni di loro sono:

  • La classe definisce hashCode () ma non equals (): Una classe implementa il metodo hashCode () ma non equals () - quindi due istanze potrebbero essere uguali ma non avere gli stessi codici hash. Questo rientra nella categoria delle cattive pratiche. 
  • Cattivo confronto del valore int con una costante lunga: Il codice sta confrontando un valore int con una costante lunga che non rientra nell'intervallo di valori che può essere rappresentato come un valore int. Questo confronto è vacuo e probabilmente produrrà un risultato inaspettato. Questo rientra nella categoria di correttezza. 
  • TestCase non ha test: class è un JUnit TestCase ma non ha implementato alcun metodo di test. Questo modello è anche nella categoria di correttezza. 

FindBugs è un progetto open-source, quindi puoi visualizzare, contribuire o monitorare lo stato di avanzamento del codice sorgente su GitHub. 

Nel findbugs-exclude.xml file, vogliamo impedire a FindBugs di analizzare alcune classi (usando le espressioni regolari) nei nostri progetti, come le classi di risorse generate automaticamente e le classi manifest generate automaticamente. Inoltre, se usi Dagger, vogliamo che FindBug non controlli le classi generate da Dagger. Possiamo anche dire a FindBugs di ignorare alcune regole se vogliamo. 

                 

E infine, includeremo il findbugs compito in quality.gradle:

applica plugin: findbugs 'findbugs' (tipo: FindBugs) descrizione 'Esegui findbugs' group 'verify' classes = file ("$ project.buildDir / intermediates / classes") source 'src' classpath = files () effort 'max 'reportLevel = "high" excludeFilter file (' ./ code_quality_tools / findbugs-exclude.xml ') reports xml.enabled = false html.enabled = true ignoreFailures = false

Nella prima riga sopra, abbiamo applicato FindBugs come plugin Gradle e poi abbiamo creato un'attività chiamata findbugs. Le proprietà chiave del findbugs compito di cui ci occupiamo veramente sono: 

  • classi: le classi da analizzare.
  • sforzo: il livello di sforzo dell'analisi. Il valore specificato dovrebbe essere uno di minpredefinito, o max.  Tieni presente che i livelli più elevati aumentano la precisione e trovano più bug al costo del tempo di esecuzione e del consumo di memoria.
  • REPORTLEVEL: la soglia di priorità per segnalare bug. Se impostato su basso, vengono segnalati tutti i bug. Se impostato su medio (predefinito), vengono segnalati errori di media e alta priorità. Se impostato su alto, vengono segnalati solo i bug con priorità alta.
  • excludeFilter: il nome file di un filtro che specifica i bug da escludere dalla segnalazione, che abbiamo già creato. 

È quindi possibile eseguire lo script Gradle visitando la finestra dello strumento Gradle, aprendo la cartella del gruppo di verifica e quindi facendo clic su findbugs per eseguire l'operazione. O lanciarlo dalla riga di comando:

findleugs di gradle

Un report verrà generato anche quando l'attività ha terminato l'esecuzione. Questo sarà disponibile a modulo app> build> rapporti> findbugs. Il plug-in FindBugs è un altro plug-in liberamente disponibile per il download e l'integrazione con IntelliJ IDEA o Android Studio.

Android Lint

Lint è un altro strumento di analisi del codice, ma questo viene fornito con Android Studio per impostazione predefinita. Controlla i file di origine del progetto Android per potenziali bug e ottimizzazioni per correttezza, sicurezza, prestazioni, usabilità, accessibilità e internazionalizzazione. 

Per configurare Lint, devi includere il lintOptions blocco a livello di modulo build.gradle file:

lintOptions abortOnError false quiet true lintConfig file ('./ code_quality_tools / lint.xml')

Le opzioni chiave di Lint di cui ci occupiamo sono: 

  • abortOnError: se lint deve impostare il codice di uscita del processo se vengono trovati errori.
  • silenzioso: se disattivare la segnalazione dell'avanzamento dell'analisi.
  • lintConfig: il file di configurazione predefinito da utilizzare.

Il tuo lint.xml il file può includere problemi che Lint deve ignorare o modificare, come nell'esempio seguente:

      

È possibile eseguire manualmente Lint da Android Studio facendo clic su Analizzare menu, scegliendo Ispeziona codice ...  (l'ambito dell'ispezione è l'intero progetto), quindi facendo clic su ok pulsante per procedere.

Puoi anche lanciare Lint visitando la finestra dello strumento Gradle, aprendo il menu verifica gruppo, quindi facendo clic su garza. Infine, puoi eseguirlo tramite la riga di comando.

Su Windows:

gradlew lint

Su Linux o Mac:

./ gradlew lint

Un report verrà generato anche quando l'attività ha terminato l'esecuzione, che è disponibile all'indirizzo modulo app> build> output> lint-results.html.

Bonus: StrictMode

StrictMode è uno strumento per sviluppatori che aiuta a impedire agli sviluppatori del tuo progetto di eseguire accidentalmente I / O flash o I / O di rete sul thread principale, poiché ciò può portare a rallentare o non rispondere all'app. Aiuta anche a impedire la visualizzazione delle finestre di dialogo ANR (App Not Responding). Con i problemi di StrictMode corretti, la tua app diventerà più reattiva e l'utente godrà di un'esperienza più fluida. StrictMode utilizza due set di criteri per applicare le sue regole:

  • Politiche VM: protezione da cattive pratiche di codifica come la mancata chiusura SQLiteCursor oggetti o qualsiasi closeable oggetto che è stato creato. 
  • Thread Policies: osserva operazioni come l'I / O flash e l'I / O di rete eseguiti sul thread dell'applicazione principale anziché su un thread in background. 
if (BuildConfig.DEBUG) StrictMode.setThreadPolicy (new StrictMode.ThreadPolicy.Builder () .detectDiskReads () .detectDiskWrites () .detectNetwork () // o .detectAll () per tutti i problemi rilevabili .penaltyLog () // Registro rilevato violazioni al log di sistema ... build ()); StrictMode.setVmPolicy (new StrictMode.VmPolicy.Builder () .detectLeakedSqlLiteObjects () .detectLeakedClosableObjects () .penaltyLog () .penaltyDeath () // Arresta l'intero processo alla violazione ... build ()); 

Il codice sopra può trovarsi nell'applicazione, nell'attività o in un altro componente dell'applicazione onCreate () metodo. 

Puoi saperne di più StrictMode qui su Envato Tuts+. 

Un esempio di progetto Android che implementa tutto quanto sopra incluso set di regole degli strumenti per un tipico progetto Android può essere trovato nel repository GitHub di questo post.

Conclusione

In questo tutorial, hai imparato come garantire un codice Android di alta qualità utilizzando gli strumenti di analisi del codice statico: quali sono, i vantaggi del loro utilizzo e come utilizzare Checkstyle, FindBugs, Lint, PMD e StrictMode nella tua applicazione. Vai avanti e prova questi strumenti: potresti scoprire alcuni problemi nel codice che non ti aspettavi.

Nel frattempo, dai uno sguardo ad alcuni dei nostri altri corsi e tutorial sullo sviluppo di app per Android!