Upload
droidcon-dubai
View
163
Download
1
Tags:
Embed Size (px)
Citation preview
Y U NO CRAFTSMANPaul Blundell
Who?
@blundell_apps
Competition
Tweet something about the talk with the hashtags #droidconAE and #YUNOCRAFTSMAN
#droidconAE #YUNOCRAFTSMAN
What is craftsmanship?
craftsmanshipˈkrɑːf(t)smənʃɪp/
the quality of design and work shown in something
#droidconAE #YUNOCRAFTSMAN
Coder vs Craftsman
“Make a chair”
#droidconAE #YUNOCRAFTSMAN
We’re gonna talk about...
- Improving day to day craftsmanship
- Creating a positive working environment
- The final few steps to awesomeness
- Opinionated bonus material
#droidconAE #YUNOCRAFTSMAN
Improving day to day craftsmanship
Whiteboard ideation
Brainstorming session
Help non dev team members
Pair programming
Pairing tennis
Driver & Navigator pairing
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
CI Game
#rekt
Pull Request Builder
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
CI Alarm
Xbox downtime
Social / 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 / TV
- Widget
- Wear
- Daydream
- LiveWallpaper
Behind the scenes
- Content provider
- Sync Adapter
- Deep linking / Web search deep linking
- Voice commands
Listen for feedback
Measure the data
Follow the guidelines
What happens when you don’t follow the guidelines
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 16
For more info:
https://developer.android.com/about/dashboards/index.html
Activity lifecycle callbackspublic 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()); }}
Fail Gracefully! Do not crash out there
public class ReportingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override public void uncaughtException(Thread thread, Throwable ex) { // Do necessary crash handling
crashlytics.reportCrash("user crash captured", ex); }
}
private void swallowExceptionsInRelease() { if (!BuildConfig.DEBUG) { Thread.UncaughtExceptionHandler handler = new ReportingUncaughtExceptionHandler(); Thread.currentThread().setUncaughtExceptionHandler(handler); }}
Not recommended to use on your main thread
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; } }
Robolectric is dead Long live the JVM
In summary
#droidconAE #YUNOCRAFTSMAN
#droidconAE #YUNOCRAFTSMAN
Questions?األسئلة؟
#droidconAE#YUNOCRAFTSMAN
@blundell_apps
Competition Winner
References & Attributions
novoda.com
karenknowsbest.com
experttek.co.uk
memegenerator
giphy.com
cloudfront.net
wandisco.com
electronicproducts.com
alistair.cockburn.us
deadzebra.com
dribble.com Jovie Brett
smosh.com
Dilbert
developer.android.com
gradle.org
failauthority.com
hilariousgifs.com
spin.atomicobject.com