Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Y U NO CRAFTSMAN

Xavi Rigau
October 09, 2014

Y U NO CRAFTSMAN

Presentation we gave at Droidcon Stockholm "Y U NO CRAFTSMAN".

By Paul Blundell and Xavi Rigau

Xavi Rigau

October 09, 2014
Tweet

More Decks by Xavi Rigau

Other Decks in Programming

Transcript

  1. We’re gonna talk about... - Improving day to day craftsmanship

    - Creating a positive working environment - The final few steps to awesomeness - Opinionated Bonus material
  2. 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); } }
  3. Behind the scenes - Content provider - Sync Adapter -

    Deep linking / Web search deep linking
  4. 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"' } }
  5. 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 Integer versionName "${VERSION_NAME}_${GIT_SHA}"
  6. 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
  7. 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()); } }
  8. Harden! Do not crash out there public class LoggingUncaughtExceptionHandler implements

    Thread.UncaughtExceptionHandler { private static final String TAG = "MyApp"; @Override public void uncaughtException(Thread thread, Throwable ex) { Log.wtf(TAG, "Swallowed an uncaught exception.", ex); } } private void swallowExceptionsInRelease() { if (!BuildConfig.DEBUG) { Thread.UncaughtExceptionHandler handler = new LoggingUncaughtExceptionHandler(); Thread.currentThread().setUncaughtExceptionHandler(handler); } }
  9. 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; } }