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

Building Android SDK

Building Android SDK

Presented at,
- "GoogleIO 2017 Extended" Event in Mumbai hosted by MADMeetup
- Meetup hosted by GDG Toronto Android https://www.meetup.com/toandroiddev/events/250883174/

Youtube link: https://www.youtube.com/watch?v=epwAhLWkPCY

Jigar Brahmbhatt

May 17, 2017
Tweet

More Decks by Jigar Brahmbhatt

Other Decks in Programming

Transcript

  1. Building
    Android SDK/Library
    Jigar Brahmbhatt
    @jabbar_jigariyo

    View full-size slide

  2. Importance of tech talks
    Conferences/Meetups are not about
    teaching specifics, but all about
    inspiring and enlightening others
    about a topic
    At work, one may find a guide or
    mentor, but at the end everything
    depends on self-learning
    2

    View full-size slide

  3. Why build an SDK?
    3

    View full-size slide

  4. Why build an SDK?
    To build a product around it
    A paid SDK or an open-sourced library
    4

    View full-size slide

  5. 5
    To make your code re-usable/modular
    Thinking in terms of SDK design tends to improve quality of
    program that you write
    To build a product around it
    Why build an SDK?

    View full-size slide

  6. Characteristics of a good SDK
    6
    Reference:
    How To Design A Good API and Why it Matters
    - Joshua Bloch
    - https://www.youtube.com/watch?v=heh4OeB9A-c

    View full-size slide

  7. Characteristics of a good SDK
    7
    Easy to use, even without documentation

    View full-size slide

  8. Characteristics of a good SDK
    8
    Fabric.with(context, new Crashlytics());
    Easy to use, even without documentation

    View full-size slide

  9. Characteristics of a good SDK
    9
    Picasso.with(context)
    .load(“http://i.imgur.com/DvpvklR.png")
    .into(imageView);
    Easy to use, even without documentation

    View full-size slide

  10. Characteristics of a good SDK
    10
    Must have great documentation!

    View full-size slide

  11. Characteristics of a good SDK
    11
    Difficult to misuse!

    View full-size slide

  12. Characteristics of a good SDK
    12
    ‣ Methods taking int or null values
    ‣ Should I init on main thread or worker thread?
    ‣ Ask client to have your declarations in their manifest
    ‣ Encapsulation is not just for theory
    Difficult to misuse!

    View full-size slide

  13. Characteristics of a good SDK
    13
    Difficult to misuse!
    return Collections.unmodifiableList(list);
    return list;
    ‣ Methods taking int or null values
    ‣ Should I init on main thread or worker thread?
    ‣ Ask client to have your declarations in their manifest
    ‣ Encapsulation is not just for theory

    View full-size slide

  14. 14
    @MainThread
    @WorkerThread
    @AnyThread
    @NonNull
    @IntDef, @StringDef
    Fail fast (Exceptions)
    @LayoutRes,
    @StringRes, etc
    @RequiresPermission,
    @RequiresApi
    @IntRange, @FloatRange
    Characteristics of a good SDK
    Difficult to misuse!

    View full-size slide

  15. 15
    Characteristics of a good SDK
    Easy to read and maintain for users

    View full-size slide

  16. 16
    try {

    return xyzAPI.init(context);

    } catch (PermissionsNotSatisfied ignored) {

    }
    Characteristics of a good SDK
    Easy to read and maintain for users

    View full-size slide

  17. 17
    ImageLoadingOptions imageLoadingOptions = new ImageLoadingOptions
    .Builder()

    .load(url)

    .diskCacheStrategy(DiskCacheStrategy.SOURCE)

    .build();

    ImageLoader.downloadInto(iv_optionIcon, imageLoadingOptions);
    Characteristics of a good SDK
    Easy to read and maintain for users

    View full-size slide

  18. 18
    ImageLoadingOptions imageLoadingOptions = new ImageLoadingOptions
    .Builder()

    .load(url)

    .diskCacheStrategy(DiskCacheStrategy.SOURCE)

    .build();

    ImageLoader.downloadInto(iv_optionIcon, url);
    Characteristics of a good SDK
    Easy to read and maintain for users

    View full-size slide

  19. 19
    Characteristics of a good SDK
    Use popular patterns!
    Take reference from popular SDKs!

    View full-size slide

  20. 20
    Characteristics of a good SDK
    ‣ Builder Pattern for initialization, config etc
    ‣ Fluent interfaces
    ‣ Allows values like keys to be set via manifest metadata
    ‣ Create extendable APIs for more advanced control
    ‣ Provider both sync and async versions of methods, if
    applicable
    Use popular patterns!

    View full-size slide

  21. 21
    Characteristics of a good SDK
    Solid sample code/application!
    Very very important!

    View full-size slide

  22. 22
    Characteristics of a good SDK
    Method counts
    Hurts Android specifically!

    View full-size slide

  23. 23
    Characteristics of a good SDK
    Method counts
    23
    ‣ Proguard
    ‣ Java Synthetic Method
    ‣ Libraries which your library uses
    Exploring Java's Hidden Cost
    - Jake Wharton
    - https://www.youtube.com/watch?v=WALV33rWye4

    View full-size slide

  24. 25
    Solid beginning is necessary

    View full-size slide

  25. 26
    ‣ No need to create full fledged first version
    ‣ Get core functionality/architecture VERY right
    ‣ Tip: Start your process with 2-3 page of top level
    documentation and get it validated
    ‣ Should be easy to evolve
    Solid beginning is necessary

    View full-size slide

  26. 27
    Define state of objects
    passed to/returned from
    library methods
    Reference:
    The Mutable State Monster and How to Defeat it
    - Anup Cowkur
    - https://www.youtube.com/watch?v=lE9XnvBV-ys

    View full-size slide

  27. 28
    Define state of objects
    passed to/returned from
    library methods
    @MainThread

    public void signUp(@NonNull User user, Callback callback)
    {

    Validate.notNull(user, "user");

    .............

    Auth.signUp(user, userCallback);

    }

    View full-size slide

  28. 29
    Define state of objects
    passed to/returned from
    library methods
    @MainThread

    public void signUp(@NonNull User user, Callback callback)
    {

    Validate.notNull(user, "user");

    .............

    Auth.signUp(user, userCallback);

    }
    What if client change this user in middle of something?

    View full-size slide

  29. 30
    Define state of objects
    passed to/returned from
    library methods
    @MainThread

    public void signUp(@NonNull User user, Callback callback)
    {

    Validate.notNull(user, "user");

    .............

    Auth.signUp(new User.Builder(user).build(), callback);

    }

    View full-size slide

  30. Use interface type in an API
    instead of implementation type
    (Can’t stress enough)

    View full-size slide

  31. Use interface type in an API
    instead of implementation type
    sendEvent(HashMap events)

    View full-size slide

  32. Use interface type in an API
    instead of implementation type
    sendEvent(HashMap events)
    sendEvent(HashMap events)

    View full-size slide

  33. Use interface type in an API
    instead of implementation type
    sendEvent(Map events)
    sendEvent(HashMap events)
    sendEvent(HashMap events)

    View full-size slide

  34. Use interface type in an API
    instead of implementation type
    setTextToAView(String text)

    View full-size slide

  35. Use interface type in an API
    instead of implementation type
    setTextToAView(String text)
    setTextToAView(CharSequence text)

    View full-size slide

  36. Resource Prefix

    View full-size slide

  37. Resource Prefix
    ‣ Remember resources like abc_actionbar_etc_etc?
    ‣ Prefix your resources to save from potential issues
    or misuse after manifest merger
    ‣ Utilize power of Gradle!

    View full-size slide

  38. Resource Prefix
    ‣ Remember resources like abc_actionbar_etc_etc?
    ‣ Prefix your resources to save from potential issues
    or misuse after manifest merger
    ‣ Utilize power of Gradle!
    android {

    resourcePrefix 'haptik_'

    }

    View full-size slide

  39. Resource Prefix
    ‣ Remember resources like abc_actionbar_etc_etc?
    ‣ Prefix your resources to save from potential issues
    or misuse after manifest merger
    ‣ Utilize power of Gradle!
    android {

    resourcePrefix 'haptik_'

    }

    View full-size slide

  40. Use ${applicationId} without fail

    View full-size slide

  41. Use ${applicationId} without fail
    android:authorities="${applicationId}.haptiklib.fileprovider"

    android:exported="false"

    android:grantUriPermissions="true">

    android:resource="@xml/yourlib_provider_paths" />


    View full-size slide

  42. Use ${applicationId} without fail

    android:protectionLevel="signature" />

    View full-size slide

  43. consumerProguardFiles

    View full-size slide

  44. consumerProguardFiles
    consumerProguardFiles 'proguard-consumer-rules.txt'
    Add our proguard rules in your proguard file

    View full-size slide

  45. consumerProguardFiles
    consumerProguardFiles 'proguard-consumer-rules.txt'

    View full-size slide

  46. Beware of default variant
    https://developer.android.com/studio/projects/android-library.html#publish_multiple_variants

    View full-size slide

  47. Be cautious about permissions

    View full-size slide

  48. Be cautious about permissions
    ‣ Make sure you’re not adding permissions for client
    app without clearly specifying
    ‣ Make sure your lib’s third party dependencies don’t
    add extra unnecessary permissions
    ‣ Analyze manifest of final APK via AndroidStudio
    ‣ Force remove if not necessary
    android:name="android.permission.USE_CREDENTIALS"

    tools:node="remove" />

    View full-size slide

  49. It’s DIFFICULT to build a solid SDK!

    View full-size slide

  50. It’s DIFFICULT to build a solid SDK!
    Expect to see mistakes after release

    View full-size slide

  51. Thank you
    Twitter: @jabbar_jigariyo

    View full-size slide