Top Banner
Crash Wars - The handling awakens ŽELJKO PLESAC
71

Crash Wars - The handling awakens

Jan 21, 2017

Download

Technology

Željko Plesac
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Crash Wars  - The handling awakens

Crash Wars - The handling awakens

ŽELJKO PLESAC

Page 2: Crash Wars  - The handling awakens

ANDROID NOWADAYS

1.4 billion users

23 SDK versions

1,294 device vendors with

24,093 distinct Android devices

Page 3: Crash Wars  - The handling awakens

BEAUTIFUL APPS BEST POSSIBLE UX

Page 4: Crash Wars  - The handling awakens

I believe that the details will define the difference between good and really amazing. We prefer amazing.

- ANA BAOTIĆ

Page 5: Crash Wars  - The handling awakens

CRASHES HAVE AN ENORMOUS EFFECT ON THE

UX

Page 6: Crash Wars  - The handling awakens

NOBODY LIKES CRASHES*.

* EXCEPT QA

Page 7: Crash Wars  - The handling awakens

PROVIDE A BETTER CRASH EXPERIENCEYou should try to minimise your crashes.

Optimise your apps in a way you are able to detect crashes

even before they occur.

Page 8: Crash Wars  - The handling awakens

HOW TO PROVIDE A BETTER CRASH EXPERIENCE?

Page 9: Crash Wars  - The handling awakens

STATIC CODE CHECKERS

Page 10: Crash Wars  - The handling awakens

STATIC CODE CHECKERS

• Lint, PMD, Checkstyle, FindBugs

• ErrorProne

• SonarQube

• Facebook Infer

Page 11: Crash Wars  - The handling awakens

public class DataUtils {

public boolean testMethod(String test){ return test == null && test.length() == 0; } }

Page 12: Crash Wars  - The handling awakens

BUILD YOUR OWN “STATIC CODE CHECKERS” - USE CUSTOM LINT RULES

• define custom Lint rules that are best suited to your needs

• user/project/team specific

Page 13: Crash Wars  - The handling awakens

IF YOU’RE USING STATIC CODE CHECKERS, DON’T CHEAT.

Page 14: Crash Wars  - The handling awakens

Be a perfectionist.

Page 15: Crash Wars  - The handling awakens

WRITE TESTS.

Page 16: Crash Wars  - The handling awakens

WRITE TESTS

• black box tests, integration tests, UI tests, unit tests…

• TDD

• lot of tools - Espresso, Robolectric, Mockito…

Page 17: Crash Wars  - The handling awakens

HOW TO INCREASE YOUR TEST QUALITY?

Page 18: Crash Wars  - The handling awakens

Enforce strict testing rules.

Page 19: Crash Wars  - The handling awakens

TESTS STABILITY? Test frameworks have bugs. CI servers also. Android platform also.

Page 20: Crash Wars  - The handling awakens

HANDLE FAILURES

• all failed tests have to be examined carefully

• if your code didn’t cause them, ignore them but test them

once again when new version of testing platform is available

Page 21: Crash Wars  - The handling awakens

USE CONTINUOUS INTEGRATION

Page 22: Crash Wars  - The handling awakens

CONTINOUS INTEGRATION

Automate static code checkers & tests execution

A many products available - Jenkins, Travis, CircleCI…

Page 23: Crash Wars  - The handling awakens
Page 24: Crash Wars  - The handling awakens
Page 25: Crash Wars  - The handling awakens

HANDLE COMMON ANDROID PROBLEMS - MEMORY LEAKS

Page 26: Crash Wars  - The handling awakens

MEMORY LEAKS

• they will cause problems and crash your applications

• many great tools for detection

Page 27: Crash Wars  - The handling awakens

A memory leak detection library for Android and Java,

developed by Square (Pierre-Yves Ricau).

LEAK CANARY

Page 28: Crash Wars  - The handling awakens

• detects memory leaks in your

application, external libraries,

even Android OS itself

• it will not give you an answer

what the cause of a leak is, just

the information that the leak has

occurred

Page 29: Crash Wars  - The handling awakens

ANDROID STUDIO MEMORY PROFILERS

• Memory monitor, Heap and Allocation Trackers

• introduced in Android Studio 2.0

• can help you investigate memory leaks

Page 30: Crash Wars  - The handling awakens

ANDROID STUDIO MEMORY MONITOR

Page 31: Crash Wars  - The handling awakens

WEAK REFERENCES ARE NOT THE ANSWER TO

EVERYTHING.

Page 32: Crash Wars  - The handling awakens

USE MULTITHREADING

Page 33: Crash Wars  - The handling awakens

Android OS is multithreaded - there are other threads beside main UI thread.

Page 34: Crash Wars  - The handling awakens

ENFORCE RULES

• don’t block the main thread - even regular users will notice

flickering

• get familiar with multithreading components

• use Traceview and dmtracedump

Page 35: Crash Wars  - The handling awakens

STRICT MODE

• use Strict mode in debug builds - set penalty death • detectDiskReads() • detectDiskWrites()

Page 36: Crash Wars  - The handling awakens

DETECT ANR’S

• ANRWatchDog (link) • detects Android ANRs (Application Not

Responding) problems • can either crash your application or notify you via

callback

Page 37: Crash Wars  - The handling awakens

CRASH FAST

Page 38: Crash Wars  - The handling awakens

CRASH YOU APPLICATIONS AS SOON AS POSSIBLE

• Square’s approach to handling crashes (presentation and

video)

• organise your code in a way that it crashes as soon as

possible

• returning null values is evil

Page 39: Crash Wars  - The handling awakens

public class Person {

private String name;

private String surname;

public Person(String name, String surname) { this.name = name; this.surname = surname; }

… }

Page 40: Crash Wars  - The handling awakens

public static String getFullName(Person person) { return person.getName() + person.getSurname(); }

Page 41: Crash Wars  - The handling awakens

public static String getFullName(Person person) { if(person != null){

return person.getName() + person.getSurname(); }

else{ return null;

} }

Page 42: Crash Wars  - The handling awakens

public static String getFullName(Person person) { if (person == null) { throw new IllegalStateException("Person cannot be null!”); }

return person.getName() + person.getSurname(); }

Page 43: Crash Wars  - The handling awakens

LOG AND MEASURE

Page 44: Crash Wars  - The handling awakens

LOG AND MEASURE YOUR CRASHES

• many great tools (Crashlytics, AppsDynamics, Crittercism)

• analyse your crashes • custom ROMs causing crashes? • cheap, low quality devices? • frequency of crashes?

Page 45: Crash Wars  - The handling awakens
Page 46: Crash Wars  - The handling awakens

I don’t care about warnings, only errors.

- ME 5 YEARS AGO

Page 47: Crash Wars  - The handling awakens

THE TRY-CATCH BLOCK AND EXCEPTIONS• you should care about your handled exceptions

• they have to be logged and analysed

• should contain useful information

Page 48: Crash Wars  - The handling awakens

public class ProfilePresenterImpl implements ProfilePresenter{

public void showPersonData() { view.showFullName(PersonUtils.getFullName(person))); view.showBirthday(PersonUtils.getFormattedBirthday(person))); view.hideLoadingDialog();

} }

Page 49: Crash Wars  - The handling awakens

public class ProfilePresenterImpl implements ProfilePresenter{

public void showPersonData() { String fullName = PersonUtils.getFullName(person));

if(fullName != null){ view.showFullName(PersonUtils.getFullName(person)));

}

view.showBirthday(PersonUtils.getFormattedBirthday(person))); view.hideLoadingDialog();

} }

Page 50: Crash Wars  - The handling awakens

public class ProfilePresenterImpl implements ProfilePresenter{

public void showPersonData() { try{

String fullName = PersonUtils.getFullName(person)); if(fullName != null){ view.showFullName(PersonUtils.getFullName(person)));

}

view.showBirthday(PersonUtils.getFormattedBirthday(person))));} } catch(Exception e){ e.printStackTrace();

view.showErrorDialog(); }

} }

Page 51: Crash Wars  - The handling awakens

TIMBER

• Utility on top of Android's default Log class

• by Jake Wharton

• can be configured

Page 52: Crash Wars  - The handling awakens

CRASH REPORTING TREE

private static class CrashReportingTree extends Timber.Tree { @Override protected void log(int priority, String tag, String message, Throwable t) { if (priority == Log.VERBOSE || priority == Log.DEBUG) { return; } // will write to the crash report but NOT to logcat Crashlytics.log(message); if (t != null) { Crashlytics.logException(t); } }}

Page 53: Crash Wars  - The handling awakens

CRASH REPORTING TREE

@Overridepublic void onCreate() { super.onCreate(); CrashlyticsCore crashlyticsCore = new CrashlyticsCore.Builder()

.disabled(BuildConfig.DEBUG).build(); Fabric.with(this, new Crashlytics.Builder().core(crashlyticsCore).build());

if (BuildConfig.DEBUG) { Timber.plant(new Timber.DebugTree()); } else { Timber.plant(new CrashReportingTree()); } }

Page 54: Crash Wars  - The handling awakens

public class ProfilePresenterImpl implements ProfilePresenter{

public void showPersonData() { try{

String fullName = PersonUtils.getFullName(person)); if(fullName != null){ view.showFullName(PersonUtils.getFullName(person)));

}

view.showBirthday(PersonUtils.getFormattedBirthday(person))));} } catch(Exception e){ Timber.e(e, “Failure in “ + getClass().getSimpleName());

view.showErrorDialog(); }

} }

Page 55: Crash Wars  - The handling awakens

HIDE CRASHES FROM YOUR USERS

Page 56: Crash Wars  - The handling awakens

Crashes are just exceptions, which are not handled by your application*.

* IN MOST CASES

Page 57: Crash Wars  - The handling awakens

APP CRASH HANDLERS

• define custom app crash handler in everyone of your

production builds

• avoid ugly system dialogs

• watch out for app restart loops!

Page 58: Crash Wars  - The handling awakens

public class AppCrashHandler implements Thread.UncaughtExceptionHandler { private Activity liveActivity; public AppCrashHandler(Application application) { application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityResumed(Activity activity) { liveActivity = activity; } @Override public void onActivityPaused(Activity activity) { liveActivity = null; } }); } @Override public void uncaughtException(Thread thread, Throwable ex) { if(liveActivity != null){ Intent intent = new Intent(getApplicationContext(), MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); liveActivity.finish(); liveActivity.startActivity(intent); } System.exit(0); } }

CUSTOM CRASH HANDLER

Page 59: Crash Wars  - The handling awakens

APPLICATION CLASS

@Overridepublic void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(new AppCrashHandler(this)); }

Page 60: Crash Wars  - The handling awakens

EXAMPLE

Page 61: Crash Wars  - The handling awakens

GOOGLE PLAY FEATURES

Page 62: Crash Wars  - The handling awakens

UTILISE GOOGLE PLAY TOOLS

• alpha/beta test

• staged rollouts

Page 63: Crash Wars  - The handling awakens

HARSH TRUTH

Page 64: Crash Wars  - The handling awakens

THERE IS NO SUCH THING AS 100% CRASH FREE ANDROID

APPLICATION.

Page 65: Crash Wars  - The handling awakens

DEVICE FRAGMENTATION.

Page 66: Crash Wars  - The handling awakens

THINGS ARE GOING TO BECOME EVEN MORE

COMPLICATED.

Page 67: Crash Wars  - The handling awakens
Page 68: Crash Wars  - The handling awakens

MultiWindow support, Jack compiler, new APIs, deprecated

APIs, new programming languages…

ANDROID IS GETTING NEW FEATURES.

Page 69: Crash Wars  - The handling awakens

ROUNDUP.

Page 70: Crash Wars  - The handling awakens

Care

Minimise

Hide

Page 71: Crash Wars  - The handling awakens

Thank you!

Visit www.infinum.co or find us on social networks:

infinum.co infinumco infinumco infinum

@ZELJKOPLESAC [email protected]