Android goes Asynchronous

Post on 23-Jun-2015

503 views 0 download

description

Speaker: Arne Limburg 7. November 2013 | W-JAX München Eine Anwendung, die sich mit einer "Application not Responding"-Meldung verabschiedet, ist der Worst Case. Auch wenn Android einige Konzepte zum Thema Asynchronität bietet, steckt hier der Teufel im Detail. Diese Session stellt die existierenden Konzepte vor, diskutiert die jeweiligen Anwendungsfälle, erläutert Pitfalls und geht auf den Umgang mit ihnen ein.

Transcript of Android goes Asynchronous

Arne Limburg | open knowledge GmbH

Android goes Asynchronous @ArneLimburg

@_openknowledge

Arne Limburg | open knowledge GmbH

Android goes Asynchronous @ArneLimburg

@_openknowledge

Agenda

Einleitung

Performance

Asynchronität

Prozesse & Threads

Prozess• Betriebssystemebene• Mindestens einer pro Applikation• Separat pro Komponente möglich• Gruppierung möglich

manifest.xml<manifest ...> <activity ... android:process=":private.process" ... </activity> <activity ... android:process="de.openknowledge..." ... </activity></manifest>

Prozesszustände

• Foreground– Activity (active)– Service

(bound, startForeground, onStart, ...)• Visible (paused Activity)• Service (via startService)• Background (stopped Activity)• Empty

Prozesse & Threads

Thread• Applikationsebene• Mindestens einer pro Applikation

(UI-Thread)• Weitere möglich

Blockieren des UI-Threads vermeiden

Agenda

Einleitung

Performance

Asynchronität

AsynchronitätPerformance

Agenda

Einleitung

im Android-Kern

in einer App

Agenda

Performance

Asynchronität

im Android-Kern

in einer App

What‘s new in Jelly Bean?

What‘s new in Jelly Bean?

Performance-Gewinn durch „Project Butter“

Was ist das?

Project Butter

• VSync• Triple Buffering• Touch Responsiveness

Und was bringt das?

Was ist VSync?

http://schnurpsel.de/neue-qualitaet-bei-kommentar-spam-oder-alter-hut-223/

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

Chet Haase, Romain Guy, Android UI Toolkit Engineers auf der Google I/O 2012

What‘s new in Kitkat?

Fokus auf RAM

• Weniger RAM für Kernmodule• Aggressiveres Aufräumen von Apps

• ActivityManager.isLowRamDevice()

• SurfaceFlinger Update auf OpenGL ES 2.0

Agenda

Performance

Asynchronität

im Android Kern

in einer App

Agenda

Performance

Asynchronität

im Android Kern

in einer App

Performance einer App

Performance-Probleme• Schlechte Architektur• Datei-Zugriff• Datenbank-Zugriff• Netzwerkzugriff• ...• Selten schlechter Java-Code!

Tools zur Performance Analyse

• Hierarchy Viewer• Traceview• dmtracedump• Systrace

Lösung

Asynchronität

Lösung

Niemals im UI-Thread• Langlaufende Berechnungen• Datei-Zugriff• Datenbank-Zugriff

(z.B. startManagingCursor)• Netzwerkzugriff• ...

Agenda

Performance

Asynchronität

im Android Kern

in einer App

Agenda

Performance

Asynchronität

im Android Kern

in einer App

Asynchronität

Java-Bordmittel funktionieren auch in Android!

• Thread• ThreadPool• Future

Thread

public void someMethod() { Runnable runnable = new Runnable() { public void run() { // another thread } } new Thread(runnable).start(); }

ThreadPool private ExecutorService pool = Executors.newFixedThreadPool(5);

public void someMethod() { Runnable runnable = new Runnable() { public void run() { // another thread } } pool.execute(runnable); }

Future public void someMethod() { Callable<Result> callable = new Callable() { public Result call () { // calculate result } } Future<Result> future = pool.submit(callable); Result result = future.get(); }

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?

CalledFromWrongThreadException• Problem: Future blockiert

(nicht geeignet für UI-Thread)• Lösung 1: Activity.runOnUiThread

Activity.runOnUiThread

public void someMethod() { Runnable runnable = new Runnable() { public void run() { // some business logic runOnUiThread(new Runnable() {…}); } } pool.execute(runnable); }

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler

Handler

• Verschicken von Nachrichten über Thread-Grenzen hinweg

• Bindung an den erzeugenden ThreadIm UI-Thread erzeugenVon anderen Threads „Nachrichten“ an den

UI-Thread schicken

Handlerpublic class MyHandler extends Handler { public void handleMessage(Message message) { … // running in handler thread } …}

Handler

Verschicken von Nachrichten• sendMessage• sendMessageAtTime• sendMessageDelayed• sendMessageAtFrontOfQueue

Handler

public void someMethod() { Message message = handler.obtainMessage(); … handler.sendMessage(message);}

Handler

Ausführen von Aktionen• post• postAtTime• postDelayed• postAtFrontOfQueue

Handler public void onCreate(Bundle saved) { handler = new Handler(); }

public void someMethod() { Runnable runnable = new Runnable() { public void run() { handler.post(new Runnable() {…}); } } pool.execute(runnable);

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler• Lösung 3: AsyncTask

AsyncTask

Bietet• Callback-Funktionen in def. Threads

– doInBackground– onProgressUpdate– onPostExecute

• Parameter, Rückgabe-Wert, Progress-Info

AsyncTaskpublic class MyTask extends AsyncTask<A, P, R> { public R doInBackground(A… args) { … // running in background thread P progress = … publishProgress(progress); } …}

AsyncTaskpublic class MyTask extends AsyncTask<A, P, R> { … public void onProgressUpdate(P… p) { … // running in ui thread }

public void onPostExecute(R… result) { … // running in ui thread }}

AsyncTask

Nachteile:• Nur ein Parameter-Typ• Anzahl Threads?• Behandlung von Configuration-Changes

(z.B. Screen-Rotation)– onRetainNonConfigurationInstance– getLastNonConfigurationInstance– Mit Fragments: setRetainInstance

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler• Lösung 3: AsyncTask• Lösung 4: Loader

Loader

• Neu seit Android 3 (API Level 11) • Ersatz für startManagingCursor und Cursor.requery()

• Behandlung von Configuration-Changes LoaderManager.initLoader

• Requery über restartLoader• Kommunikation über LoaderCallbacks

Code Diving ...

Implementierung eines Loaders

• Ableiten von AsyncTaskLoader• Implementierung von loadInBackground()

• Optional: Überschreiben von– onCanceled– onReset

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler• Lösung 3: AsyncTask• Lösung 4: Loader• Lösung 5: Services?

Service

• Eigene Android-Komponente mit separatem Lebenszyklus

• Lang-laufende Operationen ohne UI-Interaktion

• Nicht per se asynchron

Service Lebenszyklus

IntentService

public class MyIntentService extends IntentService { … public void onHandleIntent(Intent intent) { … }}

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler• Lösung 3: AsyncTask• Lösung 4: Loader• Lösung 5: Services

Inter-Thread-Kommunikation

Wie kommen asynchron geholte Daten in den UI-Thread?• Lösung 1: Activity.runOnUiThread• Lösung 2: Handler• Lösung 3: AsyncTask• Lösung 4: Loader• Lösung 5: Services• Lösung 6: BroadcastReceiver

BroadcastReceiver

• Eigene Android-Komponente mit separatem Lebenszyklus

• Empfänger für systemweite Nachrichten• Low-Battery, Screen-Off, SMS-Received, ...• ohne eigene UI, Status Bar Notifications• Aufruf via sendBroadcast(Intent)

Code Diving ...

LocalBroadcastManager

• Nicht Teil der Android API• Im Android Support Package• Für Kommunikation innerhalb der App • Verwendung

– LocalBroadcastManager.getInstance– registerReceiver– sendBroadcast

LocalBroadcastManager

• Nicht Teil der Android API• Im Android Support Package• Für Kommunikation innerhalb der App • Verwendung

– LocalBroadcastManager.getInstance– registerReceiver– sendBroadcast

Agenda

Performance

Asynchronität

Fazit

FazitAlways take the right guy for the job!

FazitAlways take the right guy for the job!• Plain Threads

– Volle Kontrolle– Kontextgebunden– Manuelle UI-Updates– Hohes Fehlerpotential

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask

– Handling von UI-Updates– Einfache Implementierung– Callback-API– Kontextgebunden– Achtung: Anzahl Threads beachten!

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben• Loader

– Eigener Kontext– Vorgegebener Lifecycle– Wenig Dokumentation– API Level 11 (4)

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben• Loader Neu aber gut für den Job

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben• Loader Neu aber gut für den Job• Services

– Eigener Kontext– Eigenes Threading– Eigene Synchronisation– Komplizierte Callbacks

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben• Loader Neu aber gut für den Job• Services IntentService meist einfacher

FazitAlways take the right guy for the job!• Plain Threads AsyncTask meist besser• AsyncTask für einfache Aufgaben• Loader Neu aber gut für den Job• Services IntentService meist einfacher• BroadcastReceiver

Entkoppelt aber nicht asynchron

Vielen Dank für Ihre Zeit.

Kontakt:

open knowledge GmbHBismarckstr. 1326122 Oldenburg

arne.limburg@openknowledge.de

@ArneLimburg @_openknowledge

Q&A