clean android code - droidcon italiy 2014
DESCRIPTION
The benefits of Clean Code are obvious: stable programs, better maintainability, finding bugs faster and easier upgrading of software. A lot of advices have been already written about Java clean code (first of all in Robert C. Martin book), what about Android? Are the same advices valid? Or the way we write code must be different because it's a mobile platform? Are there any best practices about resources and the other Android stuff? In this talk we'll see some practical examples of how take advantage of Java and Android framework to write clean code and keep a project manageable.TRANSCRIPT
Droidcon Italy - Torino - 6/7 Febbraio 2014
Clean Android CodeFabio Collini
@fabioCollini
linkedin.com/in/fabiocollini
Folder Organizer
Freapp
nana bianca
cosenonjaviste.it
Agenda
Definizione di Clean CodeFormattazione del codiceClean code vs optimizationBest practices JavaGestione delle risorse AndroidTest
"The only way to make the deadline -- the onlyway to go fast -- is to keep the code as clean as
possible at all times."Clean code - Robert C. Martin
Definizione di Clean CodeLeggibileManutenibileEspandibileEspressivoCorrettoTestabile...
Formattazione del codice
Eclipse
Android Studio / IntelliJ
Clean codeVs
optimization
android.view.Viewint mPrivateFlags;
//...
public void setIsRootNamespace(boolean isRoot) { if (isRoot) { mPrivateFlags |= IS_ROOT_NAMESPACE; } else { mPrivateFlags &= ~IS_ROOT_NAMESPACE; }}
public boolean isRootNamespace() { return (mPrivateFlags&IS_ROOT_NAMESPACE) != 0;}
Ottimizzazione del codice
la classe View è istanziata molte volte all'interno di ogniactivity di ogni appha senso ottimizzare l'occupazione di memoriama nel codice di una app?
Rules of Optimization:Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.Michael A. Jackson
Enum
storicamente su Android erano sconsigliatecon il JIT compiler la situazione è migliorata
Per evitare creazione di oggetti gli int sono molto usatiTutte le risorse sono int nella classe R
textView.setText(100);
Caused by: android.content.res.Resources$NotFoundException:String resource ID #0x64 at android.content.res.Resources.getText(Resources.java:239) at android.widget.TextView.setText(TextView.java:3844)
textView.setText(Integer.toString(100));
SimpleCursorTreeAdapterContextCursorintString[]int[]intString[]int[]
SimpleCursorTreeAdapter
new SimpleCursorTreeAdapter(this, groupCursor, android.R.layout.simple_expandable_list_item_2, new String[]{"Column1", "Column2"}, new int[]{android.R.id.text1, android.R.id.text2}, android.R.layout.simple_list_item_1, new String[]{"Column3", "Column4"}, new int[]{android.R.id.text1, android.R.id.text2}) { //...};
Usando classi/enumContextCursorLayoutColumn[]ViewId[]LayoutColumn[]ViewId[]
ContextCursorLayoutColumnMappingLayoutColumnMapping
D on'tR epeatY ourself
The first time you do something, you just do it.The second time you do something similar, you
wince at the duplication, but you do theduplicate thing anyway. The third time you do
something similar, you refactor.Martin Fowler
WriteE verythingT wice
Coesionee
disaccoppiamento
Activity
classe base da usare per creare una interfaccia graficanei casi semplici contengono tuttopossono diventare molto grandi e difficili da gestire
Fragment
interfacce responsiveciclo di vita complicatoutili ma non semplici da usare
Custom View
classi che estendono una Viewpossono essere usate in un layoutusate per creare componenti nuoviutili anche per raggruppare codice
ButterKnife
injection delle view in una classebasato su annotation processingsemplice da usarerende il codice più leggibile
Flow e Mortar
framework sviluppati da Squarebasati su Daggersostitutivi ai fragment, semplificano il ciclo di vita
Risorse in un progetto Android
<resources> <style name="layoutStyle"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:orientation">vertical</item> <item name="android:gravity">center</item> </style>
<style name="textViewColor"> <item name="android:textSize">150sp</item> <item name="android:textColor">#515151</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> </style></resources>
<resources> <style name="layoutStyle" parent="layoutStyleBase"> <item name="android:orientation">horizontal</item> </style></resources>
<resources> <color name="textColor">#515151</color></resources>
<resources> <dimen name="textSize">150sp</dimen></resources>
<resources> <dimen name="textSize">250sp</dimen></resources>
Include di layout
equivalente di un extract methodutile quando una piccola parte del layout cambia in basealla configurazione
Tipi di risorse disponibili
LayoutDrawableStiliStringAnimazioniColor
Color state listBooleanDimensionIdIntegerArray
Il codice Java dovrebbe essereindipendente dalle configurazioni
Test
Coperto da test Vs TestabileL'architettura dell'app è fondamentale per avere codicetestabile
DaggerA fast dependency injector for Android and Java
Dagger
Object: possono essere singletonModule: classi Java che creano ObjectObjectGraph: creato runtime a partireda più moduli
Scopepublic ObjectGraph plus(Object... modules) {
}
Permette di creare oggetti legati a scope:Application
ActivityFragment
Pro di Dagger
alto disaccoppiamento delle classivalidazione compile time delle dipendenzemoduli di test con stub e mock
EventBus
permette di usare una architettura basata su eventiusando il metodo post vengono invocati i metodionEvent degli oggetti che si sono registrati conregistersimile a Otto ma non basato su annotationgestisce anche i thread in background
Uso di EventBus
Gerarchia di eventi: listener su classi baseGli eventi possono essere ParcelableCiclo di vita Activity/cambio di orientation
Test su Android
JUnitRoboelectricRobotiumEspresso...
Test Driven Development
public void testCalculator() { assertEquals(4, calculator.sum(2, 2)); }
FEST Android
public void testUi() { assertThat(layout).isVisible() .isVertical() .hasChildCount(4) .hasShowDividers(SHOW_DIVIDERS_MIDDLE);}
Quello che servirebbe...
public void testUi() { assertEquals(layout, mockup);}
Test della ui
utili per creare il caso di testaggiungendo uno wait è possibile interagire con il deviceSpoon permette di eseguire i test su più device e salvarescreenshot
Java 8
in uscita a Marzolambda expression e molte altre novitàcambierà il modo di scrivere codice
RiferimentiRobert C. Martin - Clean code
Martin Fowler - Refactoring: Improving the Design ofExisting Code
Simpler Android apps with Flow and Mortargithub.com/JakeWharton/butterknife
github.com/square/daggergithub.com/greenrobot/EventBusgithub.com/square/fest-android
Thanks for your attention!
Questions?
@fabioCollini
linkedin.com/in/fabiocollini