Slide 1

Slide 1 text

TOOLS Sebastiano Poggi Novoda, Android GDE TRADE OF THE #toolsOfTrade

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

1.3 Android Studio

Slide 7

Slide 7 text

“How can this be a NPE?” “I wish things were strongly typed, all resource IDs look like any other integer!”

Slide 8

Slide 8 text

“How can this be a NPE?” “I wish things were strongly typed, all resource IDs look like any other integer!” “Why isn’t this text R.color.red? It’s showing as black!”

Slide 9

Slide 9 text

“How can this be a NPE?” “I wish things were strongly typed, all resource IDs look like any other integer!” “Why isn’t this text R.color.red? It’s showing as black!” “I love Eclipse!”

Slide 10

Slide 10 text

“How can this be a NPE?” “I wish things were strongly typed, all resource IDs look like any other integer!” “Why isn’t this text R.color.red? It’s showing as black!” “I love Eclipse!” “What? I thought this was on the

Slide 11

Slide 11 text

“How can this be a NPE?” “I wish things were strongly typed, all resource IDs look like any other integer!” “Why isn’t this text R.color.red? It’s showing as black!” “I love Eclipse!” “What? I thought this was on the UI thread, but it’s crashing”

Slide 12

Slide 12 text

Great news!*

Slide 13

Slide 13 text

Great news!*

Slide 14

Slide 14 text

Great news!* Annotations and XML attributes will save the day

Slide 15

Slide 15 text

SURPRISE QUESTION Lint

Slide 16

Slide 16 text

Lint Born in 1979 for C

Slide 17

Slide 17 text

Lint Born in 1979 for C Performs static code analysis

Slide 18

Slide 18 text

Lint Born in 1979 for C Performs static code analysis Should be part of your CI builds

Slide 19

Slide 19 text

Lint Born in 1979 for C Performs static code analysis Should be part of your CI builds

Slide 20

Slide 20 text

tools xmlns:

Slide 21

Slide 21 text

tools xmlns: namespac

Slide 22

Slide 22 text

tools xmlns: namespace Built into the SDK/Android Studio

Slide 23

Slide 23 text

tools namespace Built into the SDK/Android Studio Safe to commit under VCS

Slide 24

Slide 24 text

tools namespace Built into the SDK/Android Studio Safe to commit under VCS (Usually)

Slide 25

Slide 25 text

tools namespace Built into the SDK/Android Studio Safe to commit under VCS (Usually)

Slide 26

Slide 26 text

tools:text="Hello world!"

Slide 27

Slide 27 text

Design-time overrides Override any android attribute /> tools:text="Hello world!"

Slide 28

Slide 28 text

Tools attributes Lint attributes

Slide 29

Slide 29 text

Tools attributes Lint attributes Design attributes

Slide 30

Slide 30 text

Tools attributes Lint attributes Design attributes

Slide 31

Slide 31 text

Tools attributes Lint attributes Design attributes

Slide 32

Slide 32 text

Should explicitly set allowBackup… Lint attribute: ignore Similar to @SuppressWarnings

Slide 33

Slide 33 text

/>

Slide 34

Slide 34 text

tools:ignore="AllowBackup" tools:ignore="AllowBackup"

Slide 35

Slide 35 text

... Lint attribute: targetApi Equivalent to @TargetApi /> <item android:elevation="8dp" tools:targetApi="HONEYCOMB" android:elevation requires API level 21(current min is 19)

Slide 36

Slide 36 text

... Lint attribute: targetApi Equivalent to @TargetApi /> <item android:elevation="8dp" tools:targetApi="LOLLIPOP" /> android:elevation requires API level 21(current min is 19)

Slide 37

Slide 37 text

... Lint attribute: targetApi Equivalent to @TargetApi <item android:elevation="8dp" tools:targetApi="LOLLIPOP" />

Slide 38

Slide 38 text

Helo, I am a typo. > tools:locale="en">

Slide 39

Slide 39 text

Helo, I am a typo. tools:locale="en">

Slide 40

Slide 40 text

Tools attributes Lint attributes Design attributes

Slide 41

Slide 41 text

> tools:context=".map.MapActivity"

Slide 42

Slide 42 text

> tools:context=".map.MapActivity"

Slide 43

Slide 43 text

>

Slide 44

Slide 44 text

> tools:showIn="@layout/activity_main"

Slide 45

Slide 45 text

> Design attribute: showIn Shows a merge in its parent layout’s include

Slide 46

Slide 46 text

> tools:menu="map"

Slide 47

Slide 47 text

> Design attribute: menu Shows a menu in the layout preview

Slide 48

Slide 48 text

> tools:actionBarNavMode="tabs"

Slide 49

Slide 49 text

> Design attribute: actionBarNavMode Shows navigation in the action bar …in theory

Slide 50

Slide 50 text

tools:layout="@layout/fragment_main"

Slide 51

Slide 51 text

Design attribute: layout Previews a fragment’s layout

Slide 52

Slide 52 text

Design attributes: list* Previews a ListView’s items, header and footer

Slide 53

Slide 53 text

Slide 54

Slide 54 text

Good read Tools of the Trade by Yours Truly https://goo.gl/hZv6S5 https://goo.gl/sia3ms

Slide 55

Slide 55 text

Good read Tools attributes http://goo.gl/lzd6YP

Slide 56

Slide 56 text

Support annotations Require support-annotations dependency

Slide 57

Slide 57 text

Support annotations Require support-annotations dependency Design attributes support-v4 (and thus v7) depends on it

Slide 58

Slide 58 text

Support annotations Require support-annotations dependency support-v4 (and thus v7) depends on it

Slide 59

Slide 59 text

public static String trim( return what.trim(); Nullability annotations @Nullable and @NonNull String what) { @Nullable }

Slide 60

Slide 60 text

Nullability annotations @Nullable and @NonNull String what) { @Nullable public static String trim( return what.trim(); Method invocation may produce NullPointerException }

Slide 61

Slide 61 text

public static String trim( if (what == null) {
 return "";
 
 return what.trim();
 Nullability annotations @Nullable and @NonNull String what) { } } @NonNull

Slide 62

Slide 62 text

Nullability annotations @Nullable and @NonNull String what) { @NonNull } } public static String trim( if (what == null) {
 return "";
 
 return what.trim();
 Condition 'what == null' is always 'false'

Slide 63

Slide 63 text

setMainTextColor(R.color.text_color);
 
 void setMainTextColor(
 textView.setTextColor(getColor(colorId)); Resource ID annotations A lot of @{resType}Res that enforce typing @Nullable Should pass resolved color instead of resource ID } int colorId) {

Slide 64

Slide 64 text

setMainTextColor(R.color.text_color);
 
 void setMainTextColor(
 textView.setTextColor(getColor(colorId)); Resource ID annotations A lot of @{resType}Res that enforce typing @Nullable int colorId) { } @ColorRes

Slide 65

Slide 65 text

Resource ID annotations @AnimatorRes @AnimRes @AnyRes @ArrayRes @AttrRes @BoolRes @ColorRes @DimenRes @DrawableRes @FractionRes @IdRes @IntegerRes @InterpolatorRes @LayoutRes @MenuRes @PluralsRes @RawRes @StringRes @StyleableRes @StyleRes @XmlRes

Slide 66

Slide 66 text

setTextColor(R.color.text_color);
 
 private void setTextColor(
 ... RGB Color annotation @ColorInt requires color value, not ID } int color) { @ColorInt

Slide 67

Slide 67 text

setTextColor(R.color.text_color);
 
 private void setTextColor(
 ... RGB Color annotation @ColorInt requires color value, not ID } @ColorInt int color) { Should pass resolved color instead of resource id here

Slide 68

Slide 68 text

setValue(20); 
 void setValue(
 // Value must be in [0, 10] Range annotations @FloatRange and @IntRange } int value) { @IntRange(from=0, to=10)

Slide 69

Slide 69 text

setValue(20); 
 void setValue(
 // Value must be in [0, 10] Range annotations @FloatRange and @IntRange } int value) { @IntRange(from=0, to=10) Value must be ≥ 0 and ≤ 10 (was 20)

Slide 70

Slide 70 text

Range annotations setCoords(new int[]{42}); 
 void setCoords(
 // Value must be int[2] @Size for arrays, collections and strings } int[] value) { @Size(2) Value must be ≥ 0 and ≤ 10 (was 20)

Slide 71

Slide 71 text

Range annotations setCoords(new int[]{42}); 
 void setCoords(
 // Value must be int[2] @Size for arrays, collections and strings } int[] value) { @Size(2) Value must be ≥ 0 and ≤ 10 (was 20) Size must be exactly 2

Slide 72

Slide 72 text

int style; TypeDef annotations The issue with avoiding enums @IntRange(from=0, to=10) static final int STYLE_MATERIAL = 0;
 static final int STYLE_HOLOYOLO = 1; style = 21;

Slide 73

Slide 73 text

@IntDef(value={STYLE_MATERIAL, STYLE_HOLOYOLO})
 @Retention(RetentionPolicy.SOURCE)
 @interface Style { } TypeDef annotations @interface definition: @IntDef and @StringDef @IntRange(from=0, to=10) static final int STYLE_MATERIAL = 0;
 static final int STYLE_HOLOYOLO = 1;

Slide 74

Slide 74 text

style = 21; TypeDef annotations @interface usage @IntRange(from=0, to=10) Must be one of: STYLE_MATERIAL, STYLE_HOLOYOLO static final int STYLE_MATERIAL = 0;
 static final int STYLE_HOLOYOLO = 1; int style; @Style

Slide 75

Slide 75 text

static final int STYLE_MATERIAL = 0;
 static final int STYLE_HOLOYOLO = 1; TypeDef annotations @interface usage @IntRange(from=0, to=10) @Style int style; style = 21; Must be one of: STYLE_MATERIAL, STYLE_HOLOYOLO

Slide 76

Slide 76 text

Threading annotations Specify thread “affinity” for methods private void test() {
 textView.setText("Oops!"); @WorkerThread }

Slide 77

Slide 77 text

Threading annotations Specify thread “affinity” for methods private void test() {
 textView.setText("Oops!"); @WorkerThread Method setText must be called from the UI thread, currently inferred thread is worker }

Slide 78

Slide 78 text

Threading annotations Specify thread “affinity” for methods Method setText must be called from the UI thread, currently inferred thread is worker @MainThread @BinderThread @UiThread @WorkerThread

Slide 79

Slide 79 text

“Architecture” annotations Contracts for methods invocation and overriding @CallSuper @CheckResult @VisibleForTesting

Slide 80

Slide 80 text

Permissions annotations Specifies calling a method requires a permission startBluetoothScan(); @RequiresPermission(Manifest.permission.BLUETOOTH) private void startBluetoothScan() { ... }

Slide 81

Slide 81 text

Permissions annotations Specifies calling a method requires a permission @RequiresPermission(Manifest.permission.BLUETOOTH) startBluetoothScan(); private void startBluetoothScan() { ... } Missing permissions required by startBluetoothScan: android.permission.BLUETOOTH

Slide 82

Slide 82 text

Proguard annotation Specifies a symbol should be kept by Proguard @Keep private void myMethod() { ... }

Slide 83

Slide 83 text

Good read Improving Code Inspection with Annotations https://goo.gl/QLyf10

Slide 84

Slide 84 text

Good read Support annotations http://goo.gl/3DTImU

Slide 85

Slide 85 text

A & Q

Slide 86

Slide 86 text

View debugging BONUS ROUND

Slide 87

Slide 87 text

View debugging Built into the SDK since API 1

Slide 88

Slide 88 text

View debugging Built into the SDK since API 1 ViewDebug

Slide 89

Slide 89 text

View debugging Built into the SDK since API 1 ViewDebug

Slide 90

Slide 90 text

public class MyCustomView extends View {
 private int fancyColor; Exported view properties Use @ExportedProperty @Nullable public int getFancyColor() {
 return fancyColor; } @ViewDebug.ExportedProperty

Slide 91

Slide 91 text

public class MyCustomView extends View {
 private int fancyColor; Exported view properties Use @ExportedProperty @Nullable @ViewDebug.ExportedProperty public int getFancyColor() {
 return fancyColor; }

Slide 92

Slide 92 text

Exported view properties Use @ExportedProperty @Nullable (
 category = "My category"
 ) public int getFancyColor() {
 return fancyColor; } @ViewDebug.ExportedProperty

Slide 93

Slide 93 text

Good read ViewDebug JavaDoc http://goo.gl/v54umV

Slide 94

Slide 94 text

A & Q (for real this time) (also, tweet questions @seebrock3r)

Slide 95

Slide 95 text

Thank you! @seebrock3r +SebastianoPoggi rock3r Sebastiano Poggi Novoda, Android GDE #toolsOfTrade