Upload
vitali-pekelis
View
102
Download
3
Embed Size (px)
Citation preview
SDK best practices
Rebecca Hamelsdorf13/9/2017
Hi!!
What is SDK
What is SDK?
what is SDK?
• SDK is a software development kit
• It’s a programing package that helps developers
to builds application for a specific platform.
• Typically it includes one or more API
Why?
Why do we need to develop an SDK?
Business need
Why do we need to develop an SDK?
But not for business reasons..
Why do we need to develop an SDK?
Business need
Internal use
Internal use..
Code reuse
Abstraction/black box
Why do we care about code reuse
● Saves time & money
Why do we care about code reuse
● Saves time & money
● Easier to maintain and change
Why do we care about code reuse
● Saves time & money
● Easier to maintain and change
● Solving bugs in a single place instead of bugs
all over the place
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Plan your public API…
Public API is the contract between the app developer and
SDK developer.
you’re officially an API designer!
Plan your public API…
Put in your mind that the developer that integrate your sdk is
not sitting next to you..
Plan your public API…
Keep it:
Easy to learn- design for “stupid” developers
Plan your public API…
Keep it:
Easy to learn
Easy to use (even without docs!!), easy to integrate.
Someone did it really easy..
Plan your public API…
Keep it:
Easy to learn
Easy to use (even without docs!!), easy to integrate.
Hard to misused!
Plan your public API…
Keep it:
Easy to learn
Easy to use (even without docs!!), easy to integrate.
Hard to misused!
Custom exceptions
Custom Exception
class ServerURLException extends RuntimeException {
public ServerURLException(String message) {
super(message);
}
}
Custom Exception
class ServerURLException extends RuntimeException {
public ServerURLException(String message) {
super(message);
}
}
static void isUrlValid(String serverURL) {
if( isNullOrEmpty(serverURL) || !isValidUrl(serverURL))
{
throw new ServerURLException(“Server URL is invalid or empty");
}
}
Plan your public API…
Keep it:
Easy to learn
Easy to use (even without docs!!), easy to integrate.
Hard to misused!
Custom exceptions
No confusing constructors - use builder pattern, static
factory pattern etc.
Builder pattern
public class User {
private final String firstName; //required
private final String lastName; //required
private final int age; //optional
private final String phone; //optional
private final String address; //optional
...
}
Builder pattern
public User(String firstName, String lastName) {this(firstName, lastName, 0);}
public User(String firstName, String lastName, int age) {this(firstName, lastName, age, "");}
public User(String firstName, String lastName, int age, String phone) {
this(firstName, lastName, age, phone, "");}
public User(String firstName, String lastName, int age, String phone, String address) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.phone = phone;
this.address = address;
}
Builder pattern
public class User {
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;}
public String getLastName() {
return lastName;}
public int getAge() {
return age;}
public String getPhone() {
return phone; }
public String getAddress() {
return address; }
Builder pattern
public class User {
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;}
public String getLastName() {
return lastName;}
public int getAge() {
return age;}
public String getPhone() {
return phone; }
public String getAddress() {
return address; }
Builder pattern
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName,
String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;}
public UserBuilder address(String address) {
this.address = address;
return this; }
public User build() {
return new User(this);
}}}
Builder pattern
User.UserBuilder("Jhon", "Doe")
.age(30)
.phone("1234567")
.address("Fake address 1234")
.build();
Plan your public API…
● Keep it:
Easy to learn
Easy to use (even without docs!!), easy to integrate.
Hard to misused!
Custom exceptions
No confusing constructors - use builder pattern, static
factory pattern etc.
Use enums, public static variables when you can.
Plan your public API…
● We don’t choose the min sdk!
we want maximum compatibility
Plan your public API…
● We don’t choose the min sdk!
we want maximum compatibility
● Try to use minimum permissions - it’s hard for the developer
to explain to THEIR users the need for permissions.
Merged Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.academy.myapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Merged Manifest
https://developer.android.com/studio/build/manifest-merge.html
Plan your public API…
● We don’t choose the min sdk!
we want maximum compatibility
● Try to use minimum permissions - it’s hard for the developer
to explain to THEIR users the need for permissions.
● Think carefully - we REALLY don’t want to change it very
often (if at all!) *adding is OK
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Plan your internal code architecture
● Exception handling - the more the merrier :)
Plan your internal code architecture
● Exception handling - the more the merrier :)
● Use the minimum needed third-party libraries
a. we want to keep our SDK light
b. we avoid depending on others
Plan your internal code architecture
● Exception handling - the more the merrier :)
● Use the minimum needed third-party libraries
a. we want to keep our SDK light
b. we avoid depending on others
● Handle missing permission cases, you are not promised
to have them
Plan your internal code architecture
● Be very mindful to data consumption and battery usage!
Plan your internal code architecture
● Be very mindful to data consumption and battery usage!
● Remember your support phase during development:
○ Deprecate - don’t kill!
○ Write logs but don’t spam, use 2 log levels (debug/production)
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Code..
● Remember resource are public by default - hide what
you need hidden.
public.xml
<resources><public name="mylib_app_name" type="string"/><public name="mylib_public_string" type="string"/>
</resources>
Code..
● Add unique prefix to resources - the developers may
have their own resources that can conflict with yours!
Code..
● Add unique prefix to resources - the developers may
have their own resources that can conflict with yours!
● Test it on different Kind of apps..
Code..
● Add unique prefix to resources - the developers may
have their own resources that can conflict with yours!
● Test it on different Kind of apps..
● you must take the life cycle of the app in consideration!
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Sample app +docs
Provide 2 kinds of docs:
Simple integration instructions + sample app
Api Overview
Sample app +docs
● Provide 2 kinds of docs:
Simple integration instructions + sample app
Api Overview
• Remember Proguard docs
proguard.config
-keep class javax.** { *; } -keep class org.** { *; } -keep class twitter4j.** { *; }
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
1. Define the service for your SDK users
2. Plan your public API
3. Plan your internal code architecture
4. Code:)
5. Sample app + docs
6. Packaging
7. Ship!
Packaging
Once we had a jar..
What can we do?
We have AAR!
What does aar contain?
The file extension for an AAR file is .aar, actually the file itself is
a zip file containing the following mandatory entries:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
/public.txt
There are also optional entries :
/assets/
/libs/name.jar
/proguard.txt
/lint.jar
Migrate from AAR to JAR ..
The file extension for an AAR file is .aar, actually the file itself is
a zip file containing the following mandatory entries:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt
/public.txt
step by step..
https://developer.android.com/studio/projects/android-library.html
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Developing SDK check list
❏ Define the service for your SDK users
❏ Plan your public API
❏ Plan your internal code architecture
❏ Code:)
❏ Sample app + docs
❏ Packaging
❏ Ship!
Battery Historian
• Battery Historian is a tool to analyze battery consumers
and events(DOZE mode).
Battery Historian
• Battery Historian is a tool to analyze battery consumers
and events(DOZE mode).
• It uses Android "bugreport" files
Battery Historian
• Battery Historian is a tool to analyze battery consumers
and events(DOZE mode).
• It uses Android "bugreport" files
• Supports Lollipop (API level 21) and later.
Battery Historian
• Battery Historian is a tool to analyze battery consumers
and events(DOZE mode).
• It uses Android "bugreport" files
• Supports Lollipop (API level 21) and later.
• Shows you where and how processes are drawing current
from the battery.
Battery Historian
• https://developer.android.com/studio/profile/battery-historian.html
• https://github.com/google/battery-historian
Stetho
• Stetho is a very powerful tool for debugging.
• It enables developers have access to the Chrome
Developer Tools feature
http://facebook.github.io/stetho/
Stetho
Questions?