Y U NO CRAFTSMAN
-
Upload
paul-blundell -
Category
Technology
-
view
1.855 -
download
0
description
Transcript of Y U NO CRAFTSMAN
Y U NO CRAFTSMANXavi Rigau & Paul Blundell
Who we are
@xrigau@blundell_apps
What is craftsmanship?
craftsmanshipˈkrɑːf(t)smənʃɪp/
the quality of design and work shown in something
Coder vs Craftsman
“Make a chair”
We’re gonna talk about...
- Improving day to day craftsmanship
- Creating a positive working environment
- The final few steps to awesomeness
- Opinionated Bonus material
Improving day to day craftsmanship
Whiteboard ideation
Brainstorming sessions
Helping non dev team members
WTF??
Pair programming
Pairing tennis
Driver & Navigator
MistakesDriver
Would make
MistakesNavigator
Would make
ActualMistakes
Best coding practices
Code reviews
Selfies & Gifs
https://github.com/thieman/github-selfies
Caring about the CI
Static analysis reports
Testing is caring
CI Game
LOL
Using the latest tools
Be “agile” build features the way that makes sense
YAGNI
Overengineering
You Ain’t Gonna Need It
GSD
Pragmatism
Creating a positive working environment
Continuous communication
Morning standups
Daily news
Hack & Tells
Dojos
Zero walls office
2 keyboards 2 mice per desk
Standing desks
Remote working
Remote working
Hal9000/Jukebox music
CI Alarm
Xbox downtime
PUB!
Hire the best (for you)
The final steps to awesomeness
That extra 5%
Optimise & leave the main thread alone
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); }}
GPU Profiling
Show Overdraw
Polish the app
Animate all the things
User features
- Second screen / Chromecast
- Widget
- Wear
- Daydream
- LiveWallpaper
Behind the scenes
- Content provider
- Sync Adapter
- Deep linking / Web search deep linking
Listen for feedback
Measure the data
Measuring Tools
Splunk MINT (a.k.a. Bugsense)
Crashlytics
Follow the guidelines
What happens when you don’t follow the guidelines
Ensureyour app listing is legit
Ensureyour app content is legit
Debug screens
Gradle all the things
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"' }}
Versioning
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}"
OpinionatedBonus
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
Follow the examples - but not too closely
Patterns that work well for us
minSdkVersion 15
For more info:
https://developer.android.com/about/dashboards/
index.html
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()); }}
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); }}
Harden! Do not crash out there
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; } }
In summary
Questions?
@blundell_apps @xrigau
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