adb Tips
The official Android Developers page has a detailed documentation about Android Debug Bridge (adb). This post summarizes the adb commands that I (an android game developer) use daily.
adb devices
If you have more than one device/emulator attached to your computer you must specify on which device/emulator the adb command will run. adb devices command lists all the attached devices.
tututil:~ ilkinulas$ adb devices
List of devices attached
4df1574456e59feb device
emulator-5554 deviceYou can direct a command to a specific device with the -s option:
tututil:~ ilkinulas$ adb -s 4df1574456e59feb install ~/Downloads/SpadesPlus.apkadb logcat
Filter the logs of a specific tag:
tututil:~ ilkinulas$ adb logcat -s "SpadesPlus"Mute all the logs except “SpadesPlus” and “HeartsPlus” tags:
tututil:~ ilkinulas$ adb logcat SpadesPlus:D HeartsPlus:D *:SBy default logcat output format is:
priority/tag(process id) : log message
-v option lets you specify output format. For example :
adb logcat -v raw: Displays developer log message without any other meta-dataadb logcat -v threadtime -s "SpadesPlus": Displays logs with tag “SpadesPlus” with information about the thread writing the log message.
ndk-stack
ndk-stack is a tool that is distributed with the Android NDK. It allows you to filter stack traces as they appear in the output of ‘adb logcat’ and replace any address inside a shared library (*.so files) with the corresponding values.
Usage : adb logcat|ndk-stack -sym obj/local/armeabi/
Here is an example: ndk-stack will translate something like
I/DEBUG ( 1935): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 1935): Build fingerprint: 'samsung/t03gxx/t03g:4.3/JSS15J/N7100XXUENB2:user/release-keys'
I/DEBUG ( 1935): Revision: '11'
I/DEBUG ( 1935): pid: 18705, tid: 18724, name: Thread-1076 >>> net.peakgames.Trivia <<<
I/DEBUG ( 1935): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 646d8250
...
...
...
I/DEBUG ( 1935): backtrace:
I/DEBUG ( 1935): #00 pc 0013b250 <unknown>
I/DEBUG ( 1935): #01 pc 000a12d9 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (WidgetGroup::visualize()+24)
I/DEBUG ( 1935): #02 pc 0008e601 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (QuizStage::visualize()+252)
I/DEBUG ( 1935): #03 pc 0009f54d /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (MultiStageApplication::visualize()+12)
I/DEBUG ( 1935): #04 pc 00092ee7 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (TriviaApp::visualize()+302)
I/DEBUG ( 1935): #05 pc 00094c81 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (Java_net_peakgames_Trivia_JNILib_Step+176)
I/DEBUG ( 1935): #06 pc 0001ea50 /system/lib/libdvm.so (dvmPlatformInvoke+116)
I/DEBUG ( 1935): #07 pc 0004f667 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
I/DEBUG ( 1935): #08 pc 00000214 /dev/ashmem/dalvik-jit-code-cache (deleted)into more readable output (see the line numbers in the stack stace?):
********** Crash dump: **********
Build fingerprint: 'samsung/t03gxx/t03g:4.3/JSS15J/N7100XXUENB2:user/release-keys'
pid: 18705, tid: 18724, name: Thread-1076 >>> net.peakgames.Trivia <<<
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 646d8250
Stack frame #00 pc 0013b250 <unknown>
Stack frame #01 pc 000a12d9 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (WidgetGroup::visualize()+24): Routine visualize in ../../../../Engine/WidgetGroup.cpp:105
Stack frame #02 pc 0008e601 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (QuizStage::visualize()+252): Routine visualize in ../../QuizStage.cpp:1002
Stack frame #03 pc 0009f54d /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (MultiStageApplication::visualize()+12): Routine visualize in ../../../../Engine/MultiStageApplication.cpp:61
Stack frame #04 pc 00092ee7 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (TriviaApp::visualize()+302): Routine visualize in ../../TriviaApp.cpp:357
Stack frame #05 pc 00094c81 /data/app-lib/net.peakgames.Trivia-2/libTrivia.so (Java_net_peakgames_Trivia_JNILib_Step+176): Routine Java_net_peakgames_Trivia_JNILib_Step in ../../android/AndroidMain.cpp:198
Stack frame #06 pc 0001ea50 /system/lib/libdvm.so (dvmPlatformInvoke+116)
Stack frame #07 pc 0004f667 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
Stack frame #08 pc 00000214 /dev/ashmem/dalvik-jit-code-cache (deleted)adb push/pull
Command below copies (uploads) “my_movie.mp4” file to the Movies directory on the sdcard of the attached device. No need to open a file manager!
tututil:~ ilkinulas$ adb push ~/Downloads/my_movie.mp4 /sdcard/Movies
2171 KB/s (75515666 bytes in 33.959s)Similarly you can copy (download) a file from the attached android device to your computer:
tututil:~ ilkinulas$ adb pull /sdcard/Movies/my_movie.mp4
4213 KB/s (75515666 bytes in 17.501s)adb shell
Android devices come with a shell program that you can use to execute commands. To enter a remote shell on a device/emulator just type adb shell. To exit the remote shell type “exit” or “CTRL+D”. You can also issue single commands without entering a remote shell:
tututil:~ ilkinulas$ adb shell ps | grep net.peakgames
u0_a315 29833 1935 524728 21908 ffffffff 00000000 S net.peakgames.mobile.goalgame.android
u0_a414 29884 1935 521944 21608 ffffffff 00000000 S net.peakgames.mobile.rummi.android
u0_a431 29929 1935 661340 43428 ffffffff 00000000 S net.peakgames.mobile.spades.androidenable/disable wifi (command line)
With the adb shell command you can enable/disable wifi connection of the device. (requires root)
ilkinulas$ adb root
restarting adbd as root
ilkinulas$ adb shell svc wifi disableThis command disables wifi connection of the device from the command line.
Screen recording
You can record the display of the device (running Android 4.4 or higher) with the help of screenrecord command. Here’s an example:
adb shell screenrecord /sdcard/recording_1.mp4You can also specify quality of the recording with the --bit-rate parameter.
adb shell screenrecord --bit-rate 8000000 /sdcard/recording_2.mp4pm (package manager)
“adb shell pm $command” performs actions on application packages installed on your device. To see the detailed help just type adb shell pm.
adb shell pm list packageslists all the installed packages (apps).adb shell pm uninstall $packagenameuninstalls the specified package.
am (activity manager)
I am going to show you how to dump heap of a running android application and analyze the heap using Eclipse Memory Analyser.
First start the activity you want to monitor. In my case I am starting a game that we developed at Peak Games whose package name is net.peakgames.mobile.spades.android.
tututil:~ ilkinulas$ adb shell am start -n net.peakgames.mobile.spades.android/.SpadesPlusActivity
Starting: Intent { cmp=net.peakgames.mobile.spades.android/.SpadesPlusActivity }I need to find the process id of the application that I just started.
tututil:~ ilkinulas$ adb shell ps|grep net.peakgames.mobile.spades
u0_a447 8196 1938 669308 40732 ffffffff 00000000 S net.peakgames.mobile.spades.androidProcess id of the application is 8196. I am going to dump the heap of this process to a file on the sdcard, copy the dump file to my computer and convert it to standart file format that a profiler (in our case Eclipse Memory Analyser) can parse and display with the hprof-conv tool.
tututil:~ ilkinulas$ adb shell am dumpheap 8196 /sdcard/temp/spades-heap.dump
tututil:~ ilkinulas$ adb pull /sdcard/temp/spades-heap.dump
4137 KB/s (9381544 bytes in 2.214s)
tututil:~ ilkinulas$ hprof-conv spades-heap.dump spades-heap.hprofHere is a screenshot of the heap dump opened with Eclipse Memory Analyzer Tool.
That’s it for now. Keep calm and know your tools.