Building
Android SDK/Library
Jigar Brahmbhatt
@jabbar_jigariyo
Slide 2
Slide 2 text
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
Slide 3
Slide 3 text
Why build an SDK?
3
Slide 4
Slide 4 text
Why build an SDK?
To build a product around it
A paid SDK or an open-sourced library
4
Slide 5
Slide 5 text
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?
Slide 6
Slide 6 text
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
Slide 7
Slide 7 text
Characteristics of a good SDK
7
Easy to use, even without documentation
Slide 8
Slide 8 text
Characteristics of a good SDK
8
Fabric.with(context, new Crashlytics());
Easy to use, even without documentation
Slide 9
Slide 9 text
Characteristics of a good SDK
9
Picasso.with(context)
.load(“http://i.imgur.com/DvpvklR.png")
.into(imageView);
Easy to use, even without documentation
Slide 10
Slide 10 text
Characteristics of a good SDK
10
Must have great documentation!
Slide 11
Slide 11 text
Characteristics of a good SDK
11
Difficult to misuse!
Slide 12
Slide 12 text
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!
Slide 13
Slide 13 text
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
Slide 14
Slide 14 text
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!
Slide 15
Slide 15 text
15
Characteristics of a good SDK
Easy to read and maintain for users
Slide 16
Slide 16 text
16
try {
return xyzAPI.init(context);
} catch (PermissionsNotSatisfied ignored) {
}
Characteristics of a good SDK
Easy to read and maintain for users
Slide 17
Slide 17 text
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
Slide 18
Slide 18 text
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
Slide 19
Slide 19 text
19
Characteristics of a good SDK
Use popular patterns!
Take reference from popular SDKs!
Slide 20
Slide 20 text
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!
Slide 21
Slide 21 text
21
Characteristics of a good SDK
Solid sample code/application!
Very very important!
Slide 22
Slide 22 text
22
Characteristics of a good SDK
Method counts
Hurts Android specifically!
Slide 23
Slide 23 text
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
Slide 24
Slide 24 text
Misc Tips!
Slide 25
Slide 25 text
25
Solid beginning is necessary
Slide 26
Slide 26 text
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
Slide 27
Slide 27 text
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
Slide 28
Slide 28 text
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);
}
Slide 29
Slide 29 text
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?
Slide 30
Slide 30 text
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);
}
Slide 31
Slide 31 text
Use interface type in an API
instead of implementation type
(Can’t stress enough)
Slide 32
Slide 32 text
Use interface type in an API
instead of implementation type
sendEvent(HashMap events)
Slide 33
Slide 33 text
Use interface type in an API
instead of implementation type
sendEvent(HashMap events)
sendEvent(HashMap events)
Slide 34
Slide 34 text
Use interface type in an API
instead of implementation type
sendEvent(Map events)
sendEvent(HashMap events)
sendEvent(HashMap events)
Slide 35
Slide 35 text
Use interface type in an API
instead of implementation type
setTextToAView(String text)
Slide 36
Slide 36 text
Use interface type in an API
instead of implementation type
setTextToAView(String text)
setTextToAView(CharSequence text)
Slide 37
Slide 37 text
Resource Prefix
Slide 38
Slide 38 text
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!
Slide 39
Slide 39 text
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_'
}
Slide 40
Slide 40 text
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_'
}
Slide 41
Slide 41 text
Use ${applicationId} without fail
Slide 42
Slide 42 text
Use ${applicationId} without fail
Slide 43
Slide 43 text
Use ${applicationId} without fail
Slide 44
Slide 44 text
consumerProguardFiles
Slide 45
Slide 45 text
consumerProguardFiles
consumerProguardFiles 'proguard-consumer-rules.txt'
Add our proguard rules in your proguard file
Beware of default variant
https://developer.android.com/studio/projects/android-library.html#publish_multiple_variants
Slide 48
Slide 48 text
Be cautious about permissions
Slide 49
Slide 49 text
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
Slide 50
Slide 50 text
It’s DIFFICULT to build a solid SDK!
Slide 51
Slide 51 text
It’s DIFFICULT to build a solid SDK!
Expect to see mistakes after release