Allgemeines
Als Programmierer für J2ME von Sun war es mein Wunsch, auf Android umzusteigen.
Bei J2ME musste man eine XML-Datei als Beschreibung erstellen, dann die Midlet-Klasse mit
dem JDK übersetzen, dann ein preverify machen und den Aufruf emulator mit der XML-
Datei und einigen Parametern machen. In kurzer Zeit (unter 10 sek) war der
Emulator da, und man konnte das Midlet mehrfach starten und beenden. Wollte
man eine andere Anwendung ausführen, musste man das emulator-Programm beenden.
Mit diesem Wissen wollte ich apps für Android programmieren, mein Rechner hatte zuerst
etwa 100 MB RAM und 100MHz Takt. Leider gab
es immer wieder Probleme (Error type 1: Could not access the package manager,
Error type 2: Unable to connect to activity manager; is the system
running ?). Zudem dauerte es etwa 6 Minuten, bis der emulator gestartet war (adb -e get-state ergab die Meldung 'device'). Hierbei habe
ich das SDK 1.5 (letzte Version von Google) verwendet,
meine Bemühungen sollen im folgenden untersucht werden.
Start des Emulators
Hat man den emulator einmalig gestartet, so reichte dies irgendwie nicht aus,
um mit 'adb -e shell' darauf zugreifen zu können. Man musste mehrfach in einer
Schleife adb -e start-server, adb -e get-state aufrufen, und im Negativfall wieder
adb -e kill-server und neuer Versuch, bis get-state lieferte: 'device'.
Das Startskript für den Emulator ist hier.
Der emulator belegt 147 MB virtuellen Speicher, 49 MB Resource und
wechselnd zwischen 30% und 90% CPU.
adb (Android debug bridge) arbeitet mit Dämonen. Hiermit kann man die
Erreichbarkeit des Emulators testen:
adb -e start-server
* daemon not running. starting it now *
* daemon started successfully *
adb -e get-state
device
Ein Aufruf mit sinnvollen Parametern kann so aussehen:
emulator -avd testavd -netdelay 0 -cpu-delay 0 -netfast -noaudio -no-boot-anim
-sdcard sd_emu.bin
Im Emulator sah ich nur einen schwarzen Hintergrund mit der Schrift
'A n d r o i d', was bedeutet, dass dieser nicht komplett gestartet ist,
weil Endzustand eigentlich ein Standardbildschirm sein sollte.
Die laufenden Prozesse kann man sich in der Shell mit dem Kommando ps oder top anschauen.
Hier sehe ich die verschiedenen Benutzer root, radio, system, media,
bluetooth und app_*. Eine selbstprogrammierte Anwendung wie der oben
vorgestellte Dateimanger läuft hierbei auch unter der Benutzerkennung
app_*.
"Error Type 1: Could not access the Package Manager"
Dies erhalte ich, wenn ich nach Start des Emulators versuche:
adb -e shell pm list packages
Ich habe zuerst geglaubt, dass es ein Rechteproblem ist (leider nicht). Bei der Anmeldung an
die Shell ist man Benutzer 'root', dies müsste für pm passen. Dahinter
verbirgt sich der Aufruf
export CLASSPATH=/system/bin/framework/pm.jar
exec app_process /system/bin com.android.commands.pm.Pm "$@"
Was nichts gebracht hat, war den Aufruf 'start qemud' in der shell zu machen,
so dass dessen Status auf 'running' steht - der Fehler kam trotzdem.
Einmal beobachtet ich bei dem Fehler im logcat, dass der Package-Manager gar
noch nicht gestartet war, oder erst nachdem der Fehler kam:
...
I/SystemServer( 99): Starting Power Manager
I/SystemServer( 99): Starting Activity Manager
Error Type 1: ...
I/SystemServer( 99): Starting telephony registry
I/SystemServer( 99): Starting Package Manager // erst danach !
...
Wenn ich nach Erhalten des Fehlers nochmals probiere:
adb -e shell pm list packages,
erhalte ich eine Auflistung der Pakete ohne Fehler.
Auf Android-Seiten schlug jemand
vor, stattdessen vor adb ein 'strace -o irgendwas adb kommando' zu setzen,
bei mir brachte dies aber keine Verbesserung.
Eine Abhilfe ist bei mir also gewesen:
adb -e kill-server
adb -e start-server
adb -e logcat &
adb -e shell pm list packages
Nach einiger Zeit meldete logcat dann:
I/ServiceManager( 18): service 'activity' died
I/ServiceManager( 18): service 'package' died
...
und der Fehler 'Error type 1' kam bei Wiederholung erneut !
Es ist also m.E. nach ein Problem mit dem SystemServer bzw.
ServiceManager, dass der Package Manager gar nicht bzw. zu spät gestartet
wird, wenn (z.B. bei der Installation von Anwendungen) auf das pm-Skript
zugegriffen wird.
"Error type 2: Unable to connect to activity manager; is the system running ?'
Dies erhalte ich, wenn ich nach Start des Emulators versuche:
adb -e shell am start -D HelloActivity
Hinter am verbirgt sich der Aufruf:
export CLASSPATH=/system/framework/am.jar
exec app_process /system/bin com.android.commands.am.Am $*
Auch hier habe ich über logcat nur(!) dann Probleme festgestellt, wenn der
ActivityManager nicht rechtzeitig vorher gestartet wurde, siehe auch
'service list', ob der Dienst gestartet ist, also in den eckigen Klammern
etwas drin steht.
Abhilfe: Die gleiche wie für pm.
Zugriff mit adb auf Echtgerät/apk-Installation
Auf die sd-Karte kann man unter Linux mit klassischen mount zugreifen,
allerdings kann man vor Android 2.2 keine Anwendungen (apps) auf der sd-Karte
speichern oder dorthin verlagern. Man konnte sich mit dem Trick weiterhelfen, d
ass man die Anwendung (x.apk) und eine HTML-Datei mit einem Verweis (a
href="x.apk")
auf der sd-Karte ablegte, und die erste Datei in den Webbrowser lädt - beim
Klick auf den Verweis wird man gefragt, ob man die Anwendung x installieren oder ausführen will, womit man das Ziel erreicht hat.
Filter für logcat
Bei logcat werden i.A. sehr viele Infos rausgeworfen. Eine sinnvolle Einschränkung ist z.B.:
Wichtig: D/AndroidRuntime, D/PackageManager,
D/ActivityManager, I/SystemServer, E, W
Weniger: D/dalvikvm, D/jdwp
Sinnvoller Filter also z.B.
adb -e logcat *:I *:W *:E AndroidRuntime:D PackageManager:D ActivityManager:D
Emulator ansprechen mit telnet
Standardmaessig ist dieser an Port 5554 ansprechbar (siehe Ausgabe bei
emulator -verbose ...).
telnet localhost 5554
Hier ist die Kommandoübersicht
| Kommando | Info |
| event | simulate hardware events |
| geo | Geo-location commands |
| gsm | GSM related commands |
| kill | kill the emulator instance |
| network | manage network settings |
| power | power related commands |
| quit|exit | quit control session |
| redir | manage port redirections |
| sms | SMS related commands |
| avd | manager virtual device state |
| window | manager emulator window |
Ausführen der Anwendung
Dies geschieht mit dem Programm adb. Liegt das Programm unter /data/app,
hat den Paket-Pfad com.example.android.helloactivity und den Namen
HelloActivity als Hauptaktivität, so kann man dies starten durch Angabe
von Aktion, Kategorie und Komponente:
am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
- n com.example.android.helloactivity/com.example.android.helloactivity.HelloActivity
adb meldet dann: "Starting: Intent { ...} "
Auswirkungen einer Speicheraufrüstung
Ich habe mir ein neues Mainboard besorgt, mit knapp unter 1GB RAM und einer CPU mit
etwa 750 Mhz Takt. Die Auswirkungen waren folgende:
- Der Emulator war in einer Minute da, zudem blieb er nicht beim Wort 'A n d r o i d'
stehen, sondern lief bis zu einem Startbildschirm.
- Der virtuelle Speicher war 153 MB, die Resource etwa 129MB, die CPU-Auslastung in der
Wartezeit unter 10%, d.h. die CPU-Auslastung des alten Mainboards war durch den
Ein-/Auslagerungsspeicher (Swap) bedingt.
- Alle Dienste z.B. package, activity waren da, also waren error type x der Tatsache
geschuldet, dass der Emulator aus Speichermangel diese Dienste nicht gestartet
hatte.
Subjektives Fazit über den Emulator
Wer schon mal andere Emulatoren benutzt hat (J2ME-WTK), und einen
älteren PC mit einer langsameren CPU und bescheidenem Arbeitsspeicher
hat, kann enttäuscht sein. Nur mit Eclipse kann man gut arbeiten.
Zu dem oben beschriebenen Problemen mit Package/Activity Manager habe
ich im Internet leider nichts richtiges gefunden, also selbst Beobachtungen
anstellen müssen; der Vorschlag mit strace scheint damit zusammenzuhängen,
dass der entsprechende Service (Package, Activity) zu dem Zeitpunkt gestartet war.
Bevor man also versucht, ein Paket zu installieren und/oder auszuführen, muss man
sicherstellen, dass die Dienste da sind:
adb -e shell service check package # --> found
adb -e shell service check activity # --> found
Eine Speicheraufrüstung konnte die Probleme mit error type x zuverlässig beseitigen.