it's always your fault
TRANSCRIPT
Android Technical Lead
Applause Inc.
Przemek Jakubczyk
pjakubczyk
@pjakubczyk
1
A guide to make crashproof libraries
It's always your fault
2
Background
At Applause I am responsible for quality
Applause SDK is crash and bug reporting library
shipped to over 1000 customers
SDK works with apps around the world
3
History
Joined 2 years ago to project with no QA
Today ~1800 unit tests covering 3k methods
82% lines covered
Last major problem was support for Marshmallow
4
Other than that over 6 months of no customer complain
How your SDK should look like
Be universal
Work in every provided configuration
Be robust
Work in any environment
Be defensive
5
GRADLE
6
Just use it.
7
because it’s the base for Android build system
Gradle
use simple tricks to protect your styling
8
android {
resourcePrefix 'applause_'
}
or pass custom values to source code via DSL
defaultConfig {
resValue "string","applause_library_version”, "$version"}
Gradle
easier integration with your Groovy scripts
for example create own distribution task
task buildAll (dependsOn: 'assembleRelease', type: Copy) {
from “build/outputs/”into “another_path”
}
9
Gradle
10
Not possible :)
Often heard question. How to pass arguments to tasks?
Create new task for each configuration.
Gradle
11
task buildAll ( dependsOn:
["assembleFreeRelease, assemblePaidRelease"])
Gradle
With great power comes great responsibility
Mind the execution time
Common trick is to use VCS for versionNumber, each run takes time
If possible (please!) don’t make http calls - huge delay, timeout, offline?
Use only in tasks, not in build script evaluation.12
Java
13
Java
catching Exception doesn’t solve problem
often hides real cause
tempting but dangerous
14
try { network.getClients();} catch (Exception e) { // handle exception}
Java
Null Object Pattern
instead constantly checking for not null value
15
public interface Api { void post(String action); Api NULL = new Api() {
void post(String action){} };}
getApi().post(“Works”)
Java
NPE
Null Pointer Exception is the most popular exception thrown in runtime.
NullObject pattern partially solves the problem.
Use empty objects, collections etc;
16
List<User> fetchUsers(){ try {
return api.getAllUsers(); } catch (IOException e){
return new ArrayList<Users>(); }}
Java
Usually library is started by one static method
… and next versions provide more functionality
Init interface becomes complex
17
Java
public static void start(String baseUrl,String defaultUser,String defaultPassword,boolean cacheRequests,boolean forceHttps,int timeout)
18
Conf conf = new Conf.Builder().withUrl(“http://api.github.com”).withUser(“pjakubczyk”).withPassword(“droidcon2015Krakow”).withCache(false).withHttps(true).withTimeout(15).build();
Library.start(conf);
Java
Builder pattern organize configuration
Easier data validation
Pass only parameters user wants
Handling default values
19
Java
methods, fields, constructors
default, private, protected, public
Might sound a bit controversial
I use default or public
A.Reflection
B.Allow developers to override, it’s their responsibility 20
Android
21
Android
View.inEditMode() determines if view is drawn in Android Studio
Usually to disable other components
Let’s invert the usage
22
23
public void onFinishInflate(){TextView title = findViewById(R.id.title);if(inEditMode()) {
int count = title.getText().length();if(count > 30){
title.setTextSize(24.0f);} else {title.setTextSize(30.0f);}
}}
Android
Build.VERSION.SDK_INT
ApplicationInfo.targetSdkVersion
24
Android
usually interface for loading pictures from to web to Widget looks like this:
pictureLoader.load(“url_to_resource”, imageView);
passing arguments extending from View, Activity etc.
often lead to Memory leak
queue is flooded with requests holding all references25
Android
Android Studio is bundled with great profilers
Use memory usage graph to monitor you cache logic
Use cpu usage graph to monitor your custom views behaviour.
Use network traffic graph to check if your code doesn’t call web for stuff which suppose to be in cache
26
Android
ProGuard is outstanding tool to shrink code and inject bytecode optimizations
While shipping your code you must either provide:
copy&paste configuration to ProGuard
be transparent to ProGuard.
Configuration vs Transparency?
Transparency!27
The End
28
License
29
Thank you
30
A guide to make crashproof libraries
It's always your fault
31