10 ways to improve your android app performance

71
10 ways to improve your app performance Boris Farber Developer Advocate +borisfarber @borisfarber www.api-solutions.com

Upload: boris-farber

Post on 07-Aug-2015

1.717 views

Category:

Mobile


0 download

TRANSCRIPT

Page 1: 10 ways to improve your Android app performance

10 ways to improve your app performanceBoris Farber Developer Advocate

+borisfarber @borisfarber www.api-solutions.com

Page 2: 10 ways to improve your Android app performance

IF YOU HAVE A SMALL APP FORGET THESE SLIDES

Page 3: 10 ways to improve your Android app performance

Symptoms

● Long start time● Slow app● Janky scrolling● Irresponsive app

Page 4: 10 ways to improve your Android app performance

Activity Leaks

Page 5: 10 ways to improve your Android app performance

Why memory leaks are dangerous

● Holding references to unused Activity○ handlers + static variables

● Activity holds its view

Page 6: 10 ways to improve your Android app performance

● Activities/fragments etc - they have a life cycle● Static references

○ become dangling "pointers"○ staticActivity = staticFragment.getActivity()○ hold chain of references that lead to Activity <==

MEMORY LEAK

Page 7: 10 ways to improve your Android app performance

Outer class (Activity)

Inner class (Handler)

Page 8: 10 ways to improve your Android app performance

This is leakpublic class LeakActivity extends Activity {// ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NastyManager.getInstance().addListener(this);// ...

Page 9: 10 ways to improve your Android app performance

This is leak + fix@Overridepublic void onDestroy() { super.onDestroy();

NastyManager.getInstance().removeListener(this);}

remove listener

Page 10: 10 ways to improve your Android app performance

This is leakpublic class MainActivity extends Activity {

// ...

Handler handler; @Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// ...

handler = new Handler() {

@Override

public void handleMessage(Message msg) {

} };

// ...

Page 11: 10 ways to improve your Android app performance

What happens if ...

handler.postDelayed(...)

Page 12: 10 ways to improve your Android app performance

This is leak + fix

private static class MyHandler extends Handler {

private final WeakReference<MainActivity> mActivity;

// ...

public MyHandler(MainActivity activity) {

mActivity = new WeakReference<MainActivity>(activity);

// ...

}

@Override

public void handleMessage(Message msg) {

}

// ...

}

Page 13: 10 ways to improve your Android app performance

Outer class (Activity)

Inner class (Handler)

Page 14: 10 ways to improve your Android app performance

Prefer static to non static inner classes

● Non static Handler --> Activity leak● Both classes have a different lifetime

Page 15: 10 ways to improve your Android app performance

3 ways to handle

● Use event bus● Unregister listeners● Prefer static inner classes to non static

Page 16: 10 ways to improve your Android app performance

What you can do● Do code reviews● Understand your app structure● Use tools (MAT ...)● Print logs on callbacks

Page 17: 10 ways to improve your Android app performance

Activity LeaksQuestions ?

Page 18: 10 ways to improve your Android app performance

Scrolling

Page 19: 10 ways to improve your Android app performance

Use UI Thread only for UI

● JSON parsing● Memory (images)● Networking● Database access

Page 20: 10 ways to improve your Android app performance

What you can do to speed up scrolling

● Memory access - use library (caching, loading)● Networking access -

○ use library○ revisit your concurrency model

● Database access - use loaders

● JSON - use library DO NOT DO ANYTHING ON UI THREAD

Page 21: 10 ways to improve your Android app performance

JSON

● Small JSONs - GSON is the best● Large JSONs - Jackson, ig-json-parser

Page 22: 10 ways to improve your Android app performance

Large JSON

● Parsing has a performance effect● When converted to class with getters and

setters

Page 23: 10 ways to improve your Android app performance

UI thread

Looper.myLooper() == Looper.getMainLooper()

Page 24: 10 ways to improve your Android app performance

UI thread

● Never block it● Many java.net APIs are blocking

○ Streams○ Equals of URL class result in DNS call○ HttpURLConnection

Page 25: 10 ways to improve your Android app performance

Don't over sync

● When user doesn't need it● Use push notifications

Page 26: 10 ways to improve your Android app performance

Scrolling Questions ?

Page 27: 10 ways to improve your Android app performance

Concurrency APIs 1

Page 28: 10 ways to improve your Android app performance

Service

● Service methods run on UI thread ! ● Consider

○ IntentService○ AsyncTask○ Executors (separate bullet)○ HandlerThreads, Handlers and Loopers (separate

bullet)● Libraries do it for you

Page 29: 10 ways to improve your Android app performance

IntentService

● Single threaded● Simple/One job in a time● No job system (keep track for jobs)● No way to stop to manage it

Page 30: 10 ways to improve your Android app performance

AsyncTask

● Consider Loaders (part of support library)● Don't care about result outside of UI● Activity lifecycles - can cause a memory leak

(rotation)● Changes rapidly (grab latest and add to your

project)

Page 31: 10 ways to improve your Android app performance

Concurrency APIs 1 Questions ?

Page 32: 10 ways to improve your Android app performance

Deprecation

Page 33: 10 ways to improve your Android app performance

Deprecation

● API will be removed● Your app will not work● No way to update APIs and tools

Page 34: 10 ways to improve your Android app performance

Deprecation

● There is a compelling reason to move○ Security○ Correctness○ Performance

Page 35: 10 ways to improve your Android app performance

What you can do around deprecation

● Know and use APIs● Refactor your dependencies

Page 36: 10 ways to improve your Android app performance

Newer is better

● Prefer Toolbar to ActionBar● Prefer RecyclerView (especially for

animations)

Page 37: 10 ways to improve your Android app performance

Don't use Apache Http Connection

● Removed at M (still available as dependency)

● Use HttpURLConnection○ Simple APIa○ Small size○ Transparent compression○ Response caching

Page 38: 10 ways to improve your Android app performance

DeprecationQuestions ?

Page 39: 10 ways to improve your Android app performance

JNI

Page 40: 10 ways to improve your Android app performance

Best

● Use JNI as part of 3rd party lib

Page 41: 10 ways to improve your Android app performance

Media

● Explore advanced CPU features● Memory ● Audio● Video

Page 42: 10 ways to improve your Android app performance

Security

● Own wrapped library (SSL/crypto etc')● Rooted devices● Your own sensitive data/protocols

Page 43: 10 ways to improve your Android app performance

What you can do

● Calls are expensive● Keep the boundaries simple● Keep native code to minimum● Keep native code isolated

○ All native methods in same class or package○ Porting layer

● Test, test, test ...

Page 44: 10 ways to improve your Android app performance

JNIquestions?

Page 45: 10 ways to improve your Android app performance

Architecture

Page 46: 10 ways to improve your Android app performance

Understand app components life cycle

● Activities● Fragments● Tasks● Flags

● Add logs on callbacks

Page 47: 10 ways to improve your Android app performance

Work with framework not against ...

● Framework components have a purpose○ Specific semantics○ Used when those semantics are desired

● Don't over engineer● Keep simple

Page 48: 10 ways to improve your Android app performance

Your architecture

● Consistent● Get people on board quickly● Have someone experienced

Page 49: 10 ways to improve your Android app performance

Design your app for

● Sleeping most of the time● Responsive when "awaken"

Page 50: 10 ways to improve your Android app performance

Architecturequestions?

Page 51: 10 ways to improve your Android app performance

Concurrency APIs 2

Page 52: 10 ways to improve your Android app performance

ExecutorService

Page 53: 10 ways to improve your Android app performance

Executor Framework

● Thread pool● Callbacks● Futures

Page 54: 10 ways to improve your Android app performance

Dispatch downloadsExecutorService executor = Executors.newFixedThreadPool(1);// ...public void performAsyncCall(Handler handler) throws Exception{ // Fire a request. Future<Response> response = executor.submit(new Request (new URL("https://www.google.co.uk/")));

// Do your tasks here // ...

Page 55: 10 ways to improve your Android app performance

Dispatch downloads// ...

// block current thread

InputStream body = response.get().getBody();

// System.out.print(getStringFromInputStream(body));

// post result to handler

Message message = new Message();

Bundle bundle = new Bundle();

bundle.putString("text", "New data");

message.setData(bundle);

handler.sendMessage(message);

}

// ...

executor.shutdown();

Page 56: 10 ways to improve your Android app performance

Parse resultspublic static class Request implements Callable<Response> {

private URL url;

public Request(URL url) {

this.url = url;

System.out.println("On async http dispatcher thread " + Thread.currentThread().getId());

}

@Override

public Response call() throws Exception {

System.out.println("On worker thread from pool " + Thread.currentThread().getId());

return new Response(url.openStream());

}

}

Page 57: 10 ways to improve your Android app performance

Parse resultspublic static class Response {

private InputStream body;

public Response(InputStream body) {

this.body = body;

}

public InputStream getBody() {

System.out.println("On async http dispatcher thread " + Thread.currentThread().getId());

return body;

}

}

Page 58: 10 ways to improve your Android app performance

Executor Framework

● Excellent for mapreduce jobs

Page 59: 10 ways to improve your Android app performance

Handlers and Loopers

Page 60: 10 ways to improve your Android app performance

HandlerThread

● A thread with a message box● Saves a lot of boilerplate code● Uses Looper

Page 61: 10 ways to improve your Android app performance

Loopers and Handlers

● Looper○ Synchronized message queue to process messages

from handlers ○ Takes the next task, executes it, then takes the next

one and so on● Handler

○ Set of methods to post messages

Page 62: 10 ways to improve your Android app performance

Parse results// Has Handler in own thread, will batch update the main Activity

private class MyLooper extends Thread {

@Override

public void run() {

// Prepare the current thread to loop for events

Looper.prepare();

dispatcherThreadHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

...

}

};

Looper.loop();

}

Push handler to any other thread

Page 63: 10 ways to improve your Android app performance

Inside Looper (Android src)private Looper(boolean quitAllowed) {

// ...

mThread = Thread.currentThread();

}

/**

* Run the message queue in this thread. Be sure to call

* {@link #quit()} to end the loop.

*/

public static void loop() {

final Looper me = myLooper();

// ...

for (; ; ) { // ...

}

Page 64: 10 ways to improve your Android app performance

Concurrency APIs 2Questions ?

Page 65: 10 ways to improve your Android app performance

Miscellany

Page 66: 10 ways to improve your Android app performance

Pick 3rd party lib checklist

● Solves your problem● Plays nicely with your current dependencies● Dex method count● Dependencies● Maintenance● Runtime permissions

Page 67: 10 ways to improve your Android app performance

System Abuse

● Don't call private APIs by reflection● Don't call private native methods (NDK/C

level)● Don't use Runtime.exec● "adb shell am" to communicate with other

process is not something we want to support

Page 68: 10 ways to improve your Android app performance

Avoid complex views

● Visual clutter● Harder to maintain and draw● Use HierarchyViewer

Page 69: 10 ways to improve your Android app performance

Use TimingLogging for measuring

Page 70: 10 ways to improve your Android app performance

Best of luck in your journey wherever Android takes you

Page 71: 10 ways to improve your Android app performance

Thank you !Boris FarberDeveloper Advocate

[email protected]