Download - Y U NO CRAFTSMAN

Transcript
Page 1: Y U NO CRAFTSMAN

Y U NO CRAFTSMANXavi Rigau & Paul Blundell

Page 2: Y U NO CRAFTSMAN

Who we are

@xrigau@blundell_apps

Page 3: Y U NO CRAFTSMAN

What is craftsmanship?

craftsmanshipˈkrɑːf(t)smənʃɪp/

the quality of design and work shown in something

Page 4: Y U NO CRAFTSMAN

Coder vs Craftsman

“Make a chair”

Page 5: Y U NO CRAFTSMAN

We’re gonna talk about...

- Improving day to day craftsmanship

- Creating a positive working environment

- The final few steps to awesomeness

- Opinionated Bonus material

Page 6: Y U NO CRAFTSMAN

Improving day to day craftsmanship

Page 7: Y U NO CRAFTSMAN

Whiteboard ideation

Page 8: Y U NO CRAFTSMAN

Brainstorming sessions

Page 9: Y U NO CRAFTSMAN

Helping non dev team members

WTF??

Page 10: Y U NO CRAFTSMAN

Pair programming

Page 11: Y U NO CRAFTSMAN

Pairing tennis

Page 12: Y U NO CRAFTSMAN

Driver & Navigator

MistakesDriver

Would make

MistakesNavigator

Would make

ActualMistakes

Page 13: Y U NO CRAFTSMAN

Best coding practices

Page 14: Y U NO CRAFTSMAN

Code reviews

Page 15: Y U NO CRAFTSMAN

Selfies & Gifs

https://github.com/thieman/github-selfies

Page 16: Y U NO CRAFTSMAN

Caring about the CI

Page 17: Y U NO CRAFTSMAN

Static analysis reports

Page 18: Y U NO CRAFTSMAN

Testing is caring

Page 19: Y U NO CRAFTSMAN

CI Game

LOL

Page 20: Y U NO CRAFTSMAN

Using the latest tools

Page 21: Y U NO CRAFTSMAN

Be “agile” build features the way that makes sense

Page 22: Y U NO CRAFTSMAN

YAGNI

Overengineering

You Ain’t Gonna Need It

GSD

Page 23: Y U NO CRAFTSMAN

Pragmatism

Page 24: Y U NO CRAFTSMAN

Creating a positive working environment

Page 25: Y U NO CRAFTSMAN

Continuous communication

Page 26: Y U NO CRAFTSMAN

Morning standups

Page 27: Y U NO CRAFTSMAN

Daily news

Page 28: Y U NO CRAFTSMAN

Hack & Tells

Page 29: Y U NO CRAFTSMAN

Dojos

Page 30: Y U NO CRAFTSMAN

Zero walls office

Page 31: Y U NO CRAFTSMAN

2 keyboards 2 mice per desk

Page 32: Y U NO CRAFTSMAN

Standing desks

Page 33: Y U NO CRAFTSMAN

Remote working

Page 34: Y U NO CRAFTSMAN

Remote working

Page 35: Y U NO CRAFTSMAN

Hal9000/Jukebox music

Page 36: Y U NO CRAFTSMAN

CI Alarm

Page 37: Y U NO CRAFTSMAN

Xbox downtime

Page 38: Y U NO CRAFTSMAN

PUB!

Page 39: Y U NO CRAFTSMAN

Hire the best (for you)

Page 40: Y U NO CRAFTSMAN

The final steps to awesomeness

Page 41: Y U NO CRAFTSMAN

That extra 5%

Page 42: Y U NO CRAFTSMAN

Optimise & leave the main thread alone

Page 43: Y U NO CRAFTSMAN

Strict Mode

private void initializeStrictMode() { if (BuildConfig.DEBUG) { ThreadPolicy threadPolicy = new ThreadPolicy.Builder() .detectAll() .penaltyLog() .penaltyDeath() .build();

StrictMode.setThreadPolicy(threadPolicy);

VmPolicy vmPolicy = new VmPolicy.Builder() .detectAll() .penaltyLog() .penaltyDeath() .build();

StrictMode.setVmPolicy(vmPolicy); }}

Page 44: Y U NO CRAFTSMAN

GPU Profiling

Page 45: Y U NO CRAFTSMAN

Show Overdraw

Page 46: Y U NO CRAFTSMAN

Polish the app

Page 47: Y U NO CRAFTSMAN

Animate all the things

Page 48: Y U NO CRAFTSMAN

User features

- Second screen / Chromecast

- Widget

- Wear

- Daydream

- LiveWallpaper

Page 49: Y U NO CRAFTSMAN

Behind the scenes

- Content provider

- Sync Adapter

- Deep linking / Web search deep linking

Page 50: Y U NO CRAFTSMAN

Listen for feedback

Page 51: Y U NO CRAFTSMAN

Measure the data

Page 52: Y U NO CRAFTSMAN

Measuring Tools

Splunk MINT (a.k.a. Bugsense)

Crashlytics

Page 53: Y U NO CRAFTSMAN

Follow the guidelines

Page 54: Y U NO CRAFTSMAN

What happens when you don’t follow the guidelines

Page 55: Y U NO CRAFTSMAN

Ensureyour app listing is legit

Page 56: Y U NO CRAFTSMAN

Ensureyour app content is legit

Page 57: Y U NO CRAFTSMAN

Debug screens

Page 58: Y U NO CRAFTSMAN

Gradle all the things

Page 59: Y U NO CRAFTSMAN

Build types

buildTypes { debug { versionName "${VERSION_NAME}_${GIT_SHA}" runProguard false signingConfig signingConfigs.debug buildConfigField "String", "BUGSENSE_KEY", 'BuildConfig.INVALID' buildConfigField "boolean", "AB_TEST", 'false' } qa { runProguard false signingConfig signingConfigs.debug buildConfigField "String", "BUGSENSE_KEY", '"disSecret"' } release { runProguard true signingConfig signingConfigs.release buildConfigField "String", "BUGSENSE_KEY", '"lolNotTellingYou"' }}

Page 60: Y U NO CRAFTSMAN

Versioning

Page 61: Y U NO CRAFTSMAN

Proper versioning

ext { GIT_SHA = gitSha() CI_BUILD_NUMBER = jenkinsBuildNumber() VERSION_CODE = 19101 // scheme: MINSDK-VERSION dd-ddd VERSION_NAME = "1.0.1"}

def jenkinsBuildNumber() { // Local builds will always trump jenkins return System.getenv().BUILD_NUMBER?.toInteger() ?: 9999}

def gitSha() { return 'git rev-parse --short HEAD'.execute().text.trim()}

// ...

versionCode "${VERSION_CODE}${CI_BUILD_NUMBER}" as IntegerversionName "${VERSION_NAME}_${GIT_SHA}"

Page 62: Y U NO CRAFTSMAN

OpinionatedBonus

Page 63: Y U NO CRAFTSMAN

The dark side of AOSP

try { mWallpaper = getCurrentWallpaperLocked(context);} catch (OutOfMemoryError e) { Log.w(TAG, "No memory load current wallpaper", e);}

try { BitmapFactory.Options options =new BitmapFactory.Options(); return BitmapFactory.decodeStream(is, null, options);} catch (OutOfMemoryError e) { Log.w(TAG, "Can't decode stream", e);}

https://android.googlesource.com in WallpaperManager.java

- line 263

Page 64: Y U NO CRAFTSMAN

Follow the examples - but not too closely

Page 65: Y U NO CRAFTSMAN

Patterns that work well for us

Page 66: Y U NO CRAFTSMAN

minSdkVersion 15

For more info:

https://developer.android.com/about/dashboards/

index.html

Page 67: Y U NO CRAFTSMAN

Activity lifecycle callbacks

public interface ActivityLifecycleCallbacks { void onActivityCreated(Activity activity, Bundle savedInstanceState); void onActivityStarted(Activity activity); void onActivityResumed(Activity activity);

void onActivityPaused(Activity activity); void onActivityStopped(Activity activity); void onActivityDestroyed(Activity activity);

void onActivitySaveInstanceState(Activity activity, Bundle outState);}

public class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { … }

public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks()); }}

Page 68: Y U NO CRAFTSMAN

Harden! Do not crash out there

public class ReportingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

@Override public void uncaughtException(Thread thread, Throwable ex) { // Do necessary crash handling (fail gracefully)

crashlytics.reportCrash("user crash captured", ex); }

}

private void swallowExceptionsInRelease() { if (!BuildConfig.DEBUG) { Thread.UncaughtExceptionHandler handler = new ReportingUncaughtExceptionHandler(); Thread.currentThread().setUncaughtExceptionHandler(handler); }}

Page 69: Y U NO CRAFTSMAN

Harden! Do not crash out there

Page 70: Y U NO CRAFTSMAN

newInstance all the things!

public class WidgetImageLoader {

private final Retriever memoryRetriever; private final Retriever fileRetriever;

public static WidgetImageLoader newInstance(Context context) { Retriever memoryRetriever = MemoryRetriever.getInstance(); Retriever fileRetriever = FileRetriever.newInstance(context); return new WidgetImageLoader(memoryRetriever, fileRetriever); }

WidgetImageLoader(Retriever memoryRetriever, Retriever fileRetriever) { this.memoryRetriever = memoryRetriever; this.fileRetriever = fileRetriever; } }

Page 71: Y U NO CRAFTSMAN

Hexagonal architecture

cc. Alistair Cockburn

Page 72: Y U NO CRAFTSMAN

In summary

Page 73: Y U NO CRAFTSMAN
Page 74: Y U NO CRAFTSMAN

Questions?

@blundell_apps @xrigau

Page 75: Y U NO CRAFTSMAN

We are hiring

Liverpool, London, Berlin & New York

[email protected]

Page 76: Y U NO CRAFTSMAN

References & Attributionsnovoda.com

karenknowsbest.com

experttek.co.uk

memegenerator

giphy.com

cloudfront.net

wandisco.com

electronicproducts.com

http://alistair.cockburn.us

deadzebra.com

dribble.com Jovie Brett

smosh.com

Dilbert

developer.android.com

gradle.org

failauthority.com

hilariousgifs.com