Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Building Twitter’s SDKs 
for Android 
#droidconnl
Andy Piper 
Developer Advocate 
@andypiper
Identity 
Stability 
Distribution 
Revenue
.io
Powerful 
Lightweight
Powerful
Ease of 
Integration
Ease of Integration 
Fabric.with(this, new Crashlytics());
Extensible
Extensible 
Crashlytics.start(this);
Extensible 
Crashlytics.start(this, 5); 
Crashlytics.setListener(createCrashlyticsListener()); 
Crashlytics.setPinningInfo...
Extensible 
Crashlytics.setListener(createCrashlyticsListener()); 
Crashlytics.setPinningInfo(createPinningInfoProvider())...
Extensible 
Crashlytics.start(this, delay, listener, pinningInfo, 
debugMode);
Extensible 
Crashlytics.start(this, 0, null, null, null, true);
Fluent Pattern 
Crashlytics crashlytics = new Crashlytics.Builder() 
.delay(1) 
.listener(createCrashlyticsListener()) 
.p...
Fluent Pattern 
Fabric.with(this, new Fabric.Builder(this) 
.kits(new Crashlytics()) 
.debuggable(true) 
.logger(new Defau...
Gracefully 
Degrade
Gracefully Degrade 
if (TextUtils.isEmpty(apiKey) 
if (debuggable){ 
throw new IllegalArgumentException( 
“apiKey is null!...
Minimizing 
Permissions
Minimizing Permissions
Minimizing Permissions 
<uses-permission android:name="android.permission.INTERNET"/>
Minimizing Permissions 
Crashlytics.setUserEmail(“appuser@domain.com”);
Permissions: 
Runtime Detection 
protected boolean canCheckNetworkState() { 
String permission = 
“android.permission.ACCE...
Multiple 
Application 
Types
Multiple Application Types 
package com.example; 
import android.app.Service; 
public class MyService 
extends Service { 
...
UI from Application Context 
private WeakReference<Activity> currentActivity = new 
WeakReference<Activity>(); 
@TargetApi...
Powerful SDKs 
Ease of Integration 
Extensibility 
Support all app types 
Permission detection
Lightweight
Binary Size
Binary Size
3rd Party 
Library 
Mindfulness
3rd Party 
Library Mindfulness 
30 
20 
10 
0
3rd Party Library Mindfulness 
PROTOBUF 
KB 
OURS 
KB
Dalvik 
Method 
Count
Dalvik Method Count 
>./gradlew assemble 
… 
Unable to execute dex: method ID not in [0, 
0xffff]: 65536 
Conversion to Da...
Dalvik Method Count 
> git clone git@github.com:mihaip/dex-method-counts.git 
> cd dex-method-counts 
> ant jar 
> ./dex-m...
Minimize 
Network 
Usage
Network Usage 
10X SMALLER 
XML PROTOBUF 
100X FASTER
Reduce 
Startup 
Time
Startup Time 
Thread.start(); 
Executors.newSingleThreadExecutor();
Startup Time 
class MyThreadFactory implements ThreadFactory { 
@Override 
public Thread newThread(Runnable runnable) { 
f...
Lightweight SDKs 
Binary size 
3rd party library mindfulness 
Dalvik Method Count 
Network usage 
Startup time
Lightweight 
Powerful
Cannonball 
github.com/twitterdev
Thank You 
@andypiper 
@TwitterDev
Thanks to Andrea Falcone 
@asfalcone and the 
@Fabric team for content 
and original materials
Building Twitter's SDKs for Android
Building Twitter's SDKs for Android
Building Twitter's SDKs for Android
Building Twitter's SDKs for Android
Building Twitter's SDKs for Android
Building Twitter's SDKs for Android
Upcoming SlideShare
Loading in …5
×

Building Twitter's SDKs for Android

2,275 views

Published on

Learn hints, tips and tricks from the Twitter Fabric development team, and the principles that guided their creation of this modular and powerful SDK.

Presentation delivered at DroidconNL, Amsterdam, Nov 2014

Thanks to Andrea Falcone and the Fabric team for content and materials. You can see a lightning version of this talk delivered at Twitter Flight here -> https://www.youtube.com/watch?v=3h7jQU1AOvw&index=2&list=PLFKjcMIU2WsjUiy7UcPiWNxktpin0WDgu

Published in: Technology
  • Be the first to comment

Building Twitter's SDKs for Android

  1. 1. Building Twitter’s SDKs for Android #droidconnl
  2. 2. Andy Piper Developer Advocate @andypiper
  3. 3. Identity Stability Distribution Revenue
  4. 4. .io
  5. 5. Powerful Lightweight
  6. 6. Powerful
  7. 7. Ease of Integration
  8. 8. Ease of Integration Fabric.with(this, new Crashlytics());
  9. 9. Extensible
  10. 10. Extensible Crashlytics.start(this);
  11. 11. Extensible Crashlytics.start(this, 5); Crashlytics.setListener(createCrashlyticsListener()); Crashlytics.setPinningInfo(createPinningInfoProvider()) Crashlytics.getInstance().setDebugMode(true);
  12. 12. Extensible Crashlytics.setListener(createCrashlyticsListener()); Crashlytics.setPinningInfo(createPinningInfoProvider()); Crashlytics.getInstance().setDebugMode(true); Crashlytics.start(this, 5);
  13. 13. Extensible Crashlytics.start(this, delay, listener, pinningInfo, debugMode);
  14. 14. Extensible Crashlytics.start(this, 0, null, null, null, true);
  15. 15. Fluent Pattern Crashlytics crashlytics = new Crashlytics.Builder() .delay(1) .listener(createCrashlyticsListener()) .pinningInfo(createPinningInfoProvider()) .build(); Fabric.with(this, crashlytics);
  16. 16. Fluent Pattern Fabric.with(this, new Fabric.Builder(this) .kits(new Crashlytics()) .debuggable(true) .logger(new DefaultLogger(Log.VERBOSE)) .looper(getCustomLooper()) .executor(getCustomExecutorService()) .build());
  17. 17. Gracefully Degrade
  18. 18. Gracefully Degrade if (TextUtils.isEmpty(apiKey) if (debuggable){ throw new IllegalArgumentException( “apiKey is null!"); } else { return null; } }
  19. 19. Minimizing Permissions
  20. 20. Minimizing Permissions
  21. 21. Minimizing Permissions <uses-permission android:name="android.permission.INTERNET"/>
  22. 22. Minimizing Permissions Crashlytics.setUserEmail(“appuser@domain.com”);
  23. 23. Permissions: Runtime Detection protected boolean canCheckNetworkState() { String permission = “android.permission.ACCESS_NETWORK_STATE”; int result = context.checkCallingOrSelfPermission(permission); return (result == PackageManager.PERMISSION_GRANTED); }
  24. 24. Multiple Application Types
  25. 25. Multiple Application Types package com.example; import android.app.Service; public class MyService extends Service { }
  26. 26. UI from Application Context private WeakReference<Activity> currentActivity = new WeakReference<Activity>(); @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) private void registerLifecycleCallbacks() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { final Application app = ((Application)context); app.registerActivityLifecycleCallbacks( new ActivityLifecycleCallbacks() { @Override public void onActivityResumed(Activity activity) { currentActivity.set(activity); } }); } }
  27. 27. Powerful SDKs Ease of Integration Extensibility Support all app types Permission detection
  28. 28. Lightweight
  29. 29. Binary Size
  30. 30. Binary Size
  31. 31. 3rd Party Library Mindfulness
  32. 32. 3rd Party Library Mindfulness 30 20 10 0
  33. 33. 3rd Party Library Mindfulness PROTOBUF KB OURS KB
  34. 34. Dalvik Method Count
  35. 35. Dalvik Method Count >./gradlew assemble … Unable to execute dex: method ID not in [0, 0xffff]: 65536 Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
  36. 36. Dalvik Method Count > git clone git@github.com:mihaip/dex-method-counts.git > cd dex-method-counts > ant jar > ./dex-method-counts path/to/App.apk Read in 65490 method IDs. <root>: 65490 : 3 accessibilityservice: 6 bluetooth: 2 content: 248 pm: 22 res: 45 ... com: 53881 adjust: 283 sdk: 283
  37. 37. Minimize Network Usage
  38. 38. Network Usage 10X SMALLER XML PROTOBUF 100X FASTER
  39. 39. Reduce Startup Time
  40. 40. Startup Time Thread.start(); Executors.newSingleThreadExecutor();
  41. 41. Startup Time class MyThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable runnable) { final Thread thread = new Thread(runnable); thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND); return thread; } }
  42. 42. Lightweight SDKs Binary size 3rd party library mindfulness Dalvik Method Count Network usage Startup time
  43. 43. Lightweight Powerful
  44. 44. Cannonball github.com/twitterdev
  45. 45. Thank You @andypiper @TwitterDev
  46. 46. Thanks to Andrea Falcone @asfalcone and the @Fabric team for content and original materials

×