Android Processes & Services Jürg Luthiger University of Applied Sciences Northwestern Switzerland Institute for Mobile and Distributed Systems Ziele heute Arbeitsblatt 4 besprechen (inkl. Repetition) Sie verstehen die Konzepte Process, Thread, Service in Android und können diese einsetzen. Sie verstehen den RPC Mechanismus von Android. 2 1
Arbeitsblatt 4 File Settings.java File settings.xml mit Root Element PreferenceScreen und den Widget Elementen CheckboxPreference, EditTextPreference Eintrag der neuen Activity im Manifest File Settings über Default Menu öffnen oncreateoptionsmenu() MenuInflater aus menu.xml onoptionsitemselected() Settings Activity starten 3 Process Default Verhalten Beim Start wird für eine Android Applikation ein Prozess mit einem Thread hochgefahren. Alle weiteren Komponenten laufen in diesem Prozess und diesem Thread. Es ist möglich: Komponenten in anderen Process laufen zu lassen. Kontrolle über das Manifest File (siehe Attribute "Process"). Aus dem Process weitere Threads zu starten. 4 2
Application Not Responding (ANR) Problem Demo Reaktionsverhalten auf User Input ist entscheidend für die Akzeptanz einer Applikation Das Android System überprüft die Reaktionszeit einer Applikation und wird bei schlechtem Antwortverhalten mit einen entsprechenden Dialog reagieren 5 Triggers für ANR Dialog Android kontrolliert das Antwortverhalten über den Activity Manager und den Window Manager. Folgende Bedingungen lösen den ANR Dialog aus: Keine Reaktion auf einen Input Event (Touch Event, Key Press) innerhalb von 5 sec Ein BroadcastReceiver kann einen BroadcastEvent nicht innerhalb von 10 sec verarbeiten 6 3
Vorgehensweise Ausgangslage Eine Android Applikation läuft in einem Single (= Main) Thread. Dies bedeutet, dass jede umfangreiche Operation den ANR auslösen kann, da während dieser Zeit kein Input oder Broadcast Event verarbeitet werden kann. Folgerung Jede Methode im Main Thread soll nur das Notwendigste ausführen. Alle anderen Operation wie Netzwerkzugriff, Datenbankzugriff oder umfangreiche Berechnung sollen in Child Threads oder Services ausgelagert werden. Main Thread nie blockieren, z.b. mit Thread.wait() oder Thread.sleep() 7 Thread Main Thread (= UI Thread) Verteilen der Events an die entsprechende GUI Komponenten Zeichnen des Bildschirms Interaktion mit den GUI Widgets Child Thread Ausführen von langen Operationen wie aufwändige Berechnung, Netzwerkzugriff, Datenbank Manipulation, etc. Kein Blockieren des UI Thread ABER aus dem Child Thread können/dürfen UI Kompententen nicht manipuliert werden, da UI Toolkit nicht thread-safe ist! UI Komponenten nur aus dem UI Thread ansprechen Aus Child Thread z.b. Methode Activity.runOnUIThread(Runnable) nutzen, um z.b. Status Meldungen zu setzen. 8 4
Beispiel: Status Meldungen private String statusmessage;... private Runnable updatestatus = new Runnable() { @Override public void run() { tview.settext(statusmessage); ;... protected void startoperation() { new Thread(new Runnable() { public void run() { try { Thread.sleep(10000); statusmessage = "operation finished"; runonuithread(updatestatus); catch (InterruptedException e) { ).start();... 9 Service Services werden für lang laufende Prozesse eingesetzt. Services können von jeder Activity entkoppelt werden. Beispiele: Musik im Hintergrund abspielen, auch ohne Player Activity Polling des Internets nach RSS/Atom FeedsUpdates Halten einer Online Verbindung in einer Chat Kommunikation, obwohl aktuell ein Telefonanruf beantwortet werden muss. 10 5
Manuelle Services vs. IPC Services Services können manuell, explizit gestartet werden: startservice(intent) Services werden auch gestartet, falls ein IPC Request (Inter Process Communication) anliegt. 11 Lebenszyklus Service explizit startservice(intent) oncreate() onstart() Service läuft im Background stopservice(intent) ondestroy() 12 6
Lebenszyklus Service implizit bindservice(intent, service-connection, flags) oncreate() onbind() Service läuft im Background Client kann mit dem Service interagieren. Es existiert eine Verbindung in Form eines Kommunikationskanals unbindservice(service-connection) onunbind() ondestroy() 13 IPC in Android Jede Android Applikation hat seinen eigenen Prozess. Auch ein Service kann in einem separaten Prozess laufen. Jedoch ist ein Kommunikationsaustausch über Prozessgrenzen oft notwendig. Dies erfordert ein IPC Mechanismus oder RPC Unterstützung. Objekte, die über Prozessgrenzen kommuniziert werden sollen, müssen serialisiert und deserialisiert werden können. Android unterstützt IPC mit einer Interface Definition Language IDL, vergleichbar mit Corba oder COM. In Android heisst dies AIDL. Das AIDL-Tool kann die Kommunikationskomponenten für den Client (-> Proxy) und für den Server (-> Stub) automatisch erstellen. 14 7
Arbeiten mit AIDL Service Interface über.aidl File definieren AIDL kennt eine einfache, java-ähnliche Syntax siehe Android Dev Guide -> Tools -> aidl Proxy und Stub generieren Mit Hilfe des aidl Tools Das Eclipse Plugin hat diesen Vorgang automatisiert Service Interface, d.h. Stub implementieren Klasse Service erweitern Service für Client Zugang Methode onbind() implementieren 15 Beispiel: AIDL File package edu.mad; interface IUptimeService { int getuptimeinseconds(); in File IUptimeService.aidl und Package edu.mad 16 8
Beispiel: Server Stub public class UptimeService extends Service {... private final IUptimeService.Stub mbinder = new IUptimeService.Stub() { public int getuptimeinseconds() throws RemoteException {...; ;... Im Stub werden alle Service Methoden (hier getuptimeinseconds()) implementiert. 17 Beispiel: onbind() public IBinder onbind(intent intent) { if (UptimeService.class.getName().equals (intent.getaction())) { return mbinder; return null; Der Client wird nach dem Methodenaufruf bindservice(new Intent(IUptimeService.class.getName()), svcconn, Context.BIND_AUTO_CREATE); über die Variable svcconn die Bindung (= Proxy) zum Service erhalten. 18 9
Beispiel: Service Connection private ServiceConnection svcconn = new ServiceConnection() { @Override public void onserviceconnected(componentname name, IBinder service) { uptimeservice = IUptimeService.Stub.asInterface(service); @Override public void onservicedisconnected(componentname name) { uptimeservice = null; ; Die ServiceConnection Instanz wird bei bindservice() als Argument mitgegeben. Das Android System wird bei der Bindung die Callback Methode onserviceconnected() aufrufen. Hier wird das Service Interface im Client bekanntgemacht. 19 Aufgabe siehe Arbeitsblatt "Services" auf der Modul Website Ziel: Einsatz eines einfachen Services, der die Uptime dieses Services in Sekunden zählt. Ein Client nutzt die Service API, um die Uptime dem User anzuzeigen. 20 10