How to Love Your Developers Like Your Customers?

06ddda97beab8ddb81ac09cbc0a52c78?s=47 Ishan Khanna
February 02, 2018

How to Love Your Developers Like Your Customers?

In this talk I'll show how you can increase developer productivity of your Android Teams by adding simple debug features to your app, hacking Gradle and Android Studio to turn your Devs into Super Heroes who ship much better products faster than ever.

Everybody talks about Design, Architectures, Libraries, and whatnot, but, what we often forget is that most of the times quick wins for us as developers can be much more beneficial than tackling large refactors to use the latest technologies available so if we apply the 80-20 rule to our development workflow we can achieve so much more.
People with any level of android experience can see this talk.

06ddda97beab8ddb81ac09cbc0a52c78?s=128

Ishan Khanna

February 02, 2018
Tweet

Transcript

  1. HOW TO LOVE YOUR DEVELOPERS LIKE YOUR CUSTOMERS? Ishan Khanna

    Android @ Booking #droidkaigi @droidchef
  2. OUTLINE 1. INSPIRATION FOR THE TALK 2. DEBUG FEATURES 3.

    COMMON SCENARIOS 4. LEVERAGING THE POWER OF OPEN SOURCE 5. A COOL DEBUGGING TRICK #droidkaigi @droidchef
  3. INSPIRATION FOR THE TALK #droidkaigi @droidchef

  4. “DEBUG FEATURES” WHAT ARE THEY? #droidkaigi @droidchef

  5. WHO ARE THEY FOR? DEVELOPERS QUALITY ASSURANCE TESTERS PRODUCT OWNERS

    DESIGNERS
  6. SCENARIO 1 THE SERVER URLs #droidkaigi @droidchef

  7. PROD DEV-1 DEV-2 DEV-3 DEV-4 ANDROID APP

  8. Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://dev-2.booking.com/") .build();

  9. Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://dev-2.booking.com/") .build();

  10. PROD DEV-1 DEV-2 DEV-3 DEV-4 ANDROID APP

  11. Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://dev-3.booking.com/") .build();

  12. None
  13. SCENARIO 2 THE COPIES #droidkaigi @droidchef

  14. SEARCH RESULTS IN ENGLISH

  15. SEARCH RESULTS IN JAPANESE

  16. SIDE BY SIDE COMPARISON

  17. None
  18. SCENARIO 3 NETWORK THROTTLING #droidkaigi @droidchef

  19. public class NetworkThrottlingInterceptor implements Interceptor { private static final AtomicLong

    failRequestCount = new AtomicLong(Long.MAX_VALUE); private static boolean delayAllRequests = false; private static long minRequestDelay = 0; private static long maxRequestDelay = 0; private final Random random = new Random(4);
  20. public Response intercept(Chain chain) throws IOException { long delay =

    minRequestDelay; if( minRequestDelay != maxRequestDelay ) { delay = (long) ((random.nextDouble() * (maxRequestDelay - minRequestDelay)) + minRequestDelay); } long end = System.currentTimeMillis() + delay; long now = System.currentTimeMillis(); while( now < end ) { try { Thread.sleep( end - now); } catch (InterruptedException e) { // Nothing to do here, timing controlled by outer loop. } now = System.currentTimeMillis(); } return chain.proceed(chain.request()); }
  21. public static void delayAllRequests( long minRequestDelay, long maxRequestDelay ) {

    if( minRequestDelay == 0 && maxRequestDelay == 0 ) { delayAllRequests = false; } else { NetworkThrottlingInterceptor.minRequestDelay = minRequestDelay; NetworkThrottlingInterceptor.maxRequestDelay = maxRequestDelay; delayAllRequests = true; } }
  22. public OkHttpClient configure(@NonNull OkHttpClient client) { client = super.configure(client); return

    client.newBuilder() .addNetworkInterceptor(new NetworkThrottlingInterceptor()) .addInterceptor(new SomeOtherInterceptor()) .build(); }
  23. SCENARIO 4 UNAVAILABLE PLAY SERVICES #droidkaigi @droidchef

  24. None
  25. None
  26. SCENARIO 5 DEBUG NOTIFICATIONS #droidkaigi @droidchef

  27. APPLYING APP WIDE CHANGES • USE A LIBRARY CALLED PROCESS

    PHEONIX • WRITTEN BY JAKE WHARTON • https://github.com/JakeWharton/ProcessPhoenix #droidkaigi @droidchef
  28. START THE DEFAULT ACTIVITY IN A NEW PROCESS ProcessPhoenix.triggerRebirth(context);

  29. OR, IF YOU WANT TO LAUNCH WITH AN INTENT Intent

    nextIntent = //... ProcessPhoenix.triggerRebirth(context, nextIntent);
  30. TO CHECK IF YOUR APP IS IN PHEONIX PROCESS, TO

    SKIP INITIALIZATION IN onCreate if (ProcessPhoenix.isPhoenixProcess(this)) { return; }
  31. DON’T REINVENT THE WHEEL #droidkaigi @droidchef

  32. LEVERAGE EXISTING OPEN SOURCE SOLUTIONS #droidkaigi @droidchef

  33. SOME MUST HAVE OPEN SOURCE LIBRARIES IN YOUR PROJECT #droidkaigi

    @droidchef
  34. STETHO • DEVELOPED BY FACEBOOK • https://facebook.github.io/stetho/

  35. CHROME DEVTOOLS

  36. NETWORK INSPECTION

  37. DATABASE INSPECTION

  38. VIEW HIERARCHY INSPECTION

  39. JAVASCRIPT CONSOLE TO INTERACT WITH APP

  40. INSTALLS IN ONE LINE OF CODE public class MyApplication extends

    Application { public void onCreate() { super.onCreate(); Stetho.initializeWithDefaults(this); } }
  41. LEAK CANARY • DEVELOPED BY SQUARE • https://github.com/square/leakcanary

  42. TIMBER • DEVELOPED BY JAKE WHARTON • https://github.com/JakeWharton/timber

  43. MAKING THE MOST OF ANDROID STUDIO DEBUGGER @Override public void

    onBindViewHolder(ViewHolder holder, final int position) { final String name = values.get(position); holder.txtHeader.setText(name); holder.txtFooter.setText("Footer: " + name); }
  44. @Override public void onBindViewHolder(ViewHolder holder, final int position) { final

    String name = values.get(position); holder.txtHeader.setText(name); if (position % 3 == 0) { holder.txtHeader.setTextColor(Color.GREEN); } holder.txtFooter.setText("Footer: " + name); }
  45. None
  46. CREATE A NEW RUN CONFIG

  47. None
  48. None
  49. None
  50. None
  51. None
  52. None
  53. None
  54. GO SPREAD SOME #droidkaigi @droidchef