Android logcat ist wohl eines der wichtigsten Hilfsmittel für Android-Endwickler. Bei längeren Ausgaben wie sie bei Unit-Testing und Continuous-Integration auftreten hat logcat einen entscheidenden Nachteil: Es wird nur der Inhalt des logcat Buffers angezeigt. Dieser Buffer ist je nach Gerät zwischen 65 und 256 Kilobyte groß was ggf. zu wenig ist.
Es gibt hier aber eine Abhilfe: Man kann logcat auch mit der Android Debugging Bridge abfangen.
Hier gibt es mehrere Möglichkeiten. Die einfachste ist adb logcat
auf einer Kommandozeile einzugeben. Das ist aber nicht besonders übersichtlich. Die Ausgabe enthält nicht alle Informationen und muss real time auf den PC übertragen werden.
Besser ist es den Log in eine Datei schreiben zu lassen. Hierzu gibt es die adb logcat -f
Option.
Mit adb logcat -f
wird für die Dauer der Ausführung des adb Befehls die Ausgabe in eine Datei auf dem Android-Gerät umgeleitet. Nach Beendigung des adb logcat
kann man dann die Log-Datei mit adb pull
auf den PC kopieren und auswerten. Dies ist besonders interessant für Continuous-Integration und Unit-Testing wo die Probleme auch irgendwo in der Mitte der Ausführung auftreten können.
Man kann dies mit verschiedenen Shells in mehreren Terminals erreichen oder man automatisiert per Shell Script:
01 #!/bin/bash
11
12 set-x
13 set-e
14 shopt -s expand_aliases
15
16 alias adb=“${ANDROID_HOME}/platform-tools/adb -d“
17 alias install=“${ANDROID_HOME}/platform-tools/adb -d install“
18 alias uninstall=“${ANDROID_HOME}/platform-tools/adb -d uninstall“
19
20 function pull () {
21 “${ANDROID_HOME}/platform-tools/adb“ -d pull \
22 “/sdcard/Android/data/…/files/${1}“ \
23 “Test/target/${1}“
24 }
25
26 pushd “…“
27 # Un-Install App und Test apk from device
28 #
29 uninstall “….android“
30 uninstall “….test“
31
32 # Install App und Test apk on device
33 #
34 install “Apk/target/…-app-${…_VERSION}.apk“
35 install “Test/target/…-test-${…_VERSION}.apk“
36
37 # Clear logcat
38 #
39 adb logcat -c
40
41 # Write logcat to file on the device. (I guess that has less of a performance impact)
42 #
43 adb shell mkdir -p “/sdcard/Android/data/…/files“
44 adb logcat \
45 -v “long“ \
46 -f “/sdcard/Android/data/…/files/junit-report-smoke.logcat“ &
47 LogCat_PID=${!}
48
49 # Start smoke tests with junit xml compatible report
50 #
51 adb shell \
52 am instrument \
53 -w \
54 -e annotation android.test.suitebuilder.annotation.Smoke \
55 -e reportDir __external__ \
56 -e reportFile junit-report-smoke.xml \
57 ….test/com.zutubi.android.junitreport.JUnitReportTestRunner
58
59 # kill logcat collector process
60 #
61 kill ${LogCat_PID}
62
63 # copy result files from device
64 #
65 pull “junit-report-smoke.logcat“
66 pull “junit-report-smoke.xml“
67
68 popd
Wer Windows anstelle von Linux oder Mac OS X verwendet muss jetzt nicht auf das Log verzichten. Da Process-Management nicht gerade eine Stärke von CMD.EXE ist verwenden wir bei der Noser Engineering in solchen Fällen daher Take-Command. Das Script sieht dem Bash-Script auch recht ähnlich
01 ::#!
12
13 @ECHO OFF
14
15 IF NOT “%@eval[2 + 2]%” == “4” ( echo ^e[42mYou need TakeCommand [http://www.jpsoft.com] to execute this batch file.^e[m & EXIT /B 1)
16
17 SETLOCAL
18 OPTION //UTF8Output=yes
19 CHCP 65001
20
21 ALIAS adb=%[ANDROID_HOME]\platform-tools\adb.exe -d
22 ALIAS install=adb install
23 ALIAS uninstall=adb uninstall
24 ALIAS pull=adb pull “/sdcard/Android/data/…/files/%[1]“ “Test\target\%[1]“
25
26 PUSHD %[PROJECT_HOME]\%[PROJECT_NAME]
27 REM Un-Install App und Test apk from device
28 REM
29 uninstall “….android”
30 uninstall “….test”
31
32 REM Install App und Test apk on device
33 REM
34 install “Apk\target\…-app-%[…_VERSION].apk”
35 install “Test\target\…-test-%[…_VERSION].apk”
36
37 REM Clear logcat
38 REM
39 adb logcat -c
40
41 REM Write logcat to file on the device. (I guess that has less of a performance impact)
42 REM
43 adb shell mkdir -p “/sdcard/Android/data/…/files”
44 DETACH adb logcat ^
45 -v “long” ^
46 -f “/sdcard/Android/data/…/files/junit-report-smoke.logcat”
47 SET LogCat_PID=%[_DETACHPID]
48
49 REM Start smoke tests with junit xml compatible report
50 REM
51 adb shell ^
52 am instrument ^
53 -w ^
54 -e annotation “android.test.suitebuilder.annotation.Smoke” ^
55 -e reportDir “__external__” ^
56 -e reportFile “junit-report-smoke.xml” ^
57 “….test/com.zutubi.android.junitreport.JUnitReportTestRunner”
58
59 REM kill logcat collector process
60 REM
61 TASKEND %[LogCat_PID]
62
63 REMcopy result files from device
64 REM
65 pull “junit-report-smoke.logcat”
66 pull “junit-report-smoke.xml”
67
68 START “Run-Test Logs” %@OPTION[Editor] “Test/target/junit-report-smoke.*”
69 POPD
70
71 OPTION //UTF8Output=no
72 CHCP 850
73 ENDLOCAL
Wer sich die beiden Scripts genauer anschaut wird noch zwei weitere Extras entdecken. Zum einen die adb logcat -v
"long"
Option. Diese Option sorgt für eine umfangreiche, zweizeilige Anzeige:
01 ——— beginning of /dev/log/main
02 [ 08-22 15:04:22.938 1514: 1617 I/System.out ]
03 AsyncTask #3(ApacheHTTPLog):DefaultClientConnectionOperator.openConnection() connsock Socket[address=/198.211.122.133,port=80,localPort=56782]
04
05 [ 08-22 15:04:22.938 1514: 1617 I/System.out ]
06 AsyncTask #3(ApacheHTTPLog):Servers selected Ip address is : 198.211.122.133
07
08 [ 08-22 15:04:22.988 1514: 1617 V/SyncroAllApp ]
09 postAppListData DONE
10
11 [ 08-22 15:04:23.448 1397: 1540 W/ApplicationPackageManager ]
12 getCSCPackageItemText()
13
14 [ 08-22 15:04:23.458 2363: 2363 D/AndroidRuntime ]
15
16 >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
17
18 [ 08-22 15:04:23.458 1397: 1540 W/ApplicationPackageManager ]
19 getCSCPackageItemText()
20
21 [ 08-22 15:04:23.588 2363: 2363 E/memtrack ]
22 Couldn’t load memtrack module (No such file or directory)
23
24 [ 08-22 15:04:23.588 2363: 2363 E/android.os.Debug ]
25 failed to load memtrack module: -2
Die andere ist der JUnitReportTestRunner. Ein praktischer Instrumentation-Testrunner der eine JUnit kompatible XML Ausgabe erzeugt. Perfekt für die Weiterverarbeitung in Continuous-Integration Lösungen.