声明
- Android系统中包含很多命令行工具,包括一些Linux继承来的工具,也有不少Android系统特有工具/命令,此篇介绍一些比较重要的工具/命令。
- 这些命令来自Android框架层(源码位置:frameworks/native/cmds、frameworks/base/cmds、frameworks/av/cmds)
- 此篇中涉及代码及命令来自一台装有LineageOS 14.1的Nexus5手机。
- 此篇参考了一些书籍及论文,仅供学习使用。只介绍大概理论,不深究,就足够用了。
1 通用工具
1.1 service
service 命令允许与任意在服务管理器中注册了的系统服务进行交互:
hammerhead:/ # service
Usage: service [-h|-?]
service list
service check SERVICE
service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR ] ...
Options:
i32: Write the 32-bit integer N into the send parcel.
i64: Write the 64-bit integer N into the send parcel.
f: Write the 32-bit single-precision number N into the send parcel.
d: Write the 64-bit double-precision number N into the send parcel.
s16: Write the UTF-16 string STR into the send parcel.
该命令能用于查询,同样也能用于调用来自系统服务的方法。
hammerhead:/ # service list
Found 128 services:
0 sip: [android.net.sip.ISipService]
1 nfc: [android.nfc.INfcAdapter]
2 carrier_config: [com.android.internal.telephony.ICarrierConfigLoader]
3 phone: [com.android.internal.telephony.ITelephony]
4 isms: [com.android.internal.telephony.ISms]
5 iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]
6 simphonebook: [com.android.internal.telephony.IIccPhoneBook]
7 telecom: [com.android.internal.telecom.ITelecomService]
8 isub: [com.android.internal.telephony.ISub]
9 cmaudio: [cyanogenmod.media.ICMAudioService]
10 contexthub_service: [android.hardware.location.IContextHubService]
11 netd_listener: [android.net.metrics.INetdEventListener]
......
22 imms: [com.android.internal.telephony.IMms]
23 media_projection: [android.media.projection.IMediaProjectionManager]
24 launcherapps: [android.content.pm.ILauncherApps]
25 shortcut: [android.content.pm.IShortcutService]
26 trust: [android.app.trust.ITrustManager]
27 media_router: [android.media.IMediaRouterService]
28 media_session: [android.media.session.ISessionManager]
29 restrictions: [android.content.IRestrictionsManager]
30 print: [android.print.IPrintManager]
31 graphicsstats: [android.view.IGraphicsStats]
32 statusbar: [com.android.internal.statusbar.IStatusBarService]
......
接口名称设置在方括号内,允许你浏览 AOSP源文件来找到匹配的定义接口的.aidl文件。也可以使用如下的命令检测一项给定的服务是否存在:
hammerhead:/ # service check power
Service power: found
可以使用 service call 去直接地调用系统服务的 Binder exposed (暴露绑定) 方法。首先需要了解frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl中定义了IStatusBarService 接口。
/** @hide */
interface IStatusBarService
{
void expandNotificationsPanel();
void collapsePanels();
void disable(int what, IBinder token, String pkg);
void disableForUser(int what, IBinder token, String pkg, int userId);
void disable2(int what, IBinder token, String pkg);
void disable2ForUser(int what, IBinder token, String pkg, int userId);
void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
void setIconVisibility(String slot, boolean visible);
......
}
请注意,service call 实际上需要一个方法的代码,而不仅仅是一个方法的名字。为了找到与接口中定义的方法名称匹配的代码,你需要看一下基于接口定义的aidI工具生成的代码。比如 IStatusBarService.java中的有关摘录,此文件在:out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/statusbar/IStatusBarService.java
static final int TRANSACTION_expandNotificationsPanel = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_collapsePanels = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_disable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_disableForUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_disable2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_disable2ForUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
......
同时注意,对于整型变量FIRST_CALL_TRANSACTION 在frameworks/base/core/java/android/os/IBinder.java文件中有如下定义:
int FIRST_CALL_TRANSACTION = 0x00000001;
因此,expandNotificationsPanel()的代码是1,collapsePanels()的代码是2。如下命令将引起状态栏的扩展:
service call statusbar 1
这是一种非常简单的情况,其作用相当明显且调用的方法不带任何参数。在其他情况下,需要更仔细地查看系统服务的 API及理解设定的参数含义。另外,记住系统服务的接口不一定通过.aidl文件展示。在某些情况下,如活动管理,接口定义是直接通过硬编码在常规的Java 文件中实现而不是自动生成。在基于C的系统服务的情况下Binder的编组和解组都是直接在C 语言代码中完成。
1.2 dumpsys
其可用于查询系统服务的内部状态。事实上,每一个系统服务实现了一个dump()方法,并且可以通过 dumpsys 命令进行查询:
hammerhead:/ # dumpsys --help
usage: dumpsys
To dump all services.
or:
dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]
--help: shows this help
-l: only list services, do not dump them
-t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds
--skip SERVICES: dumps all services but SERVICES (comma-separated list)
SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it
默认情况下,如果没有系统服务名称作为参数,dumpsys 将先输出系统服务列表,然后解析它们的状态:
hammerhead:/ # dumpsys
Currently running services:
DockObserver
SurfaceFlinger
accessibility
account
activity
alarm
android.security.keystore
android.service.gatekeeper.IGateKeeperService
appops
appwidget
assetatlas
audio
backup
battery
batteryproperties
batterystats
bluetooth_manager
carrier_config
clipboard
cmaudio
cmhardware
cmlivedisplay
cmperformance
cmstatusbar
cmtelephonymanager
cmweather
commontime_management
connectivity
connectivity_metrics_logger
connmetrics
consumer_ir
content
contexthub_service
country_detector
cpuinfo
dbinfo
device_policy
deviceidle
devicestoragemonitor
diskstats
display
display.qservice
dreams
drm.drmManager
dropbox
ethernet
gfxinfo
gpu
graphicsstats
hardware_properties
imms
input
input_method
iphonesubinfo
isms
isub
jobscheduler
launcherapps
location
lock_settings
media.audio_flinger
media.audio_policy
media.camera
media.camera.proxy
media.codec
media.drm
media.extractor
media.player
media.radio
media.resource_manager
media.sound_trigger_hw
media_projection
media_router
media_session
meminfo
midi
mount
netd
netd_listener
netpolicy
netstats
network_management
network_score
network_time_update_service
nfc
notification
otadexopt
package
permission
phone
pinner
power
print
processinfo
procstats
profile
recovery
restrictions
rttmanager
samplingprofiler
scheduling_policy
search
sensorservice
serial
servicediscovery
shortcut
simphonebook
sip
soundtrigger
statusbar
telecom
telephony.registry
textservices
trust
uimode
updatelock
usagestats
usb
user
vibrator
voiceinteraction
vrmanager
wallpaper
webviewupdate
wifi
wifip2p
wifiscanner
window
-------------------------------------------------------------------------------
DUMP OF SERVICE DockObserver:
Current Dock Observer Service state:
reported state: 0
previous state: 0
actual state: 0
--------- 0.001s was the duration of dumpsys DockObserver
-------------------------------------------------------------------------------
DUMP OF SERVICE SurfaceFlinger:
Build configuration: [sf] [libui] [libgui]
Sync configuration: [using: EGL_ANDROID_native_fence_sync EGL_KHR_wait_sync]
DispSync configuration: app phase 7500000 ns, sf phase 5000000 ns, present offset 0 ns (refresh 16666667 ns)
Static screen stats:
< 1 frames: 41.227 s (0.2%)
< 2 frames: 47.859 s (0.2%)
< 3 frames: 4.114 s (0.0%)
< 4 frames: 2.872 s (0.0%)
< 5 frames: 1.647 s (0.0%)
< 6 frames: 2.513 s (0.0%)
< 7 frames: 1.409 s (0.0%)
7+ frames: 20134.619 s (99.5%)
Buffering stats:
[Layer name] <Active time> <Two buffer> <Double buffered> <Triple buffered>
[com.android.deskclock/com.android.deskclock.DeskClock] 33.40 0.394 0.440 0.560
[BootAnimation] 16.25 0.000 0.000 1.000
[com.android.settings/com.android.settings.Settings$DevelopmentSettingsActivity] 10.12 0.192 0.551 0.449
[ColorFade] 6.19 0.544 0.620 0.380
[com.android.settings/com.android.settings.FallbackHome] 5.88 0.000 0.000 1.000
[StatusBar] 4.64 0.249 0.336 0.664
[NavigationBar] 3.02 0.259 0.460 0.540
[com.android.settings/com.android.settings.Settings] 2.09 0.000 0.140 0.860
[com.cyanogenmod.trebuchet/com.android.launcher3.Launcher] 1.63 0.000 0.164 0.836
[com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity] 1.18 1.000 1.000 0.000
Visible layers (count = 11)
+ Layer 0xb688e000 (com.android.systemui.ImageWallpaper)
Region transparentRegion (this=0xb688e240, count=1)
[ 0, 0, 0, 0]
Region visibleRegion (this=0xb688e008, count=1)
[1080, 0, 2160, 1920]
Region surfaceDamageRegion (this=0xb688e044, count=1)
[ 0, 0, 0, 0]
layerStack= 0, z= 21000, pos=(0,0), size=(2160,1920), crop=( 0, 0,2160,1920), finalCrop=( 0, 0, -1, -1), isOpaque=1, invalidate=0, alpha=0xff, blur=0xff, flags=0x00000002, tr=[1.00, 0.00][0.00, 1.00]
client=0xb5c91a40
format= 2, activeBuffer=[2160x1920:2176, 3], queued-frames=0, mRefreshPending=0
mTexName=5 mCurrentTexture=-1
mCurrentCrop=[0,0,0,0] mCurrentTransform=0
mAbandoned=0
-BufferQueue mMaxAcquiredBufferCount=1, mMaxDequeuedBufferCount=2, mDequeueBufferCannotBlock=0 mAsyncMode=0, default-size=[2160x1920], default-format=2, transform-hint=00, FIFO(0)={}
[00:0x0] state=FREE
[01:0x0] state=FREE
[02:0x0] state=FREE
+ LayerDim 0xb5178400 (animation background stackId=1)
Region transparentRegion (this=0xb5178640, count=1)
......
显然,其输出是非常详细的,最重要的是,它需要你理解相应的系统服务的内部情况。如果你实现你自己的系统服务,能够查询其在运行时的状态是至关重要的。当然,如果你对解析系统服务状态不是很感兴趣,你只需要提供你想获取信息的特定服务的名称作为 dumpsys命令的一个参数:
hammerhead:/ # dumpsys power
...输出省略...
1.3 dumpstate
在某些情况下,你想要做的是获取整个系统的一个快照,而不仅仅只是系统服务,可以用dumpstate命令。
hammerhead:/ # dumpstate -h
begin
dumpstate id: 1
Dumpstate command line: dumpstate -h
usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-t][-z] [-s] [-S] [-q] [-B] [-P] [-R] [-V version]
-h: display this help message
-b: play sound file instead of vibrate, at beginning of job
-e: play sound file instead of vibrate, at end of job
-o: write to file (instead of stdout)
-d: append date to filename (requires -o)
-p: capture screenshot to filename.png (requires -o)
-t: only captures telephony sections
-z: generate zipped file (requires -o)
-s: write output to control socket (for init)
-S: write file location to control socket (for init; requires -o and -z) -q: disable vibrate
-B: send broadcast when finished (requires -o)
-P: send broadcast when started and update system properties on progress (requires -o and -B)
-R: take bugreport in remote mode (requires -o, -z, -d and -B, shouldn't be used with -P)
-V: sets the bugreport format version (valid values: 1.0)
默认情况下,如果没有系统服务名称作为参数,dumpstate 它可以查询系统的好几个部分来给你提供完整的系统状态的快照。
hammerhead:/ # dumpstate
...输出省略...
在大多数情况下,dumpstate 命令实际上是调用其他的命令如 logcat、dumpsys、ps 来检索它的信息同样其输出信息非常冗长。
1.4 rawbu
在一些情况下,你可能想要备份和恢复 /data 目录下的内容。你可以使用 rawbu 命令:
hammerhead:/ # rawbu help
Usage: rawbu COMMAND [options] [backup-file-path]
commands are:
help Show this help text.
backup Perform a backup of /data.
restore Perform a restore of /data.
options include:
-h Show this help text.
-a Backup all files.
backup-file-path Defaults to /sdcard/backup.dat .
On devices that emulate the sdcard, you will need to
explicitly specify the directory it is mapped to,
to avoid recursive backup or deletion of the backup file
during restore.
Eg. /data/media/0/backup.dat
The rawbu command allows you to perform low-level
backup and restore of the /data partition. This is
where all user data is kept, allowing for a fairly
complete restore of a device's state. Note that
because this is low-level, it will only work across
builds of the same (or very similar) device software.
用它创建一个备份:
rawbu backup /sdcard/backup.dat
该命令做的第一件事就是停止 Zygote,从而停止所有的系统服务。然后创建一个进程来从 /data 复制所有的数据,通过重启 Zygote 来结束复制,一旦数据阻塞,你能在稍后还原它:
rawbu restore /sdcard/backup.dat
显然,这个命令的输出意味着这是一个弱操作,同时你也应该意识到结果会变动。
2 特定服务工具
正如我们前面看到的,已经存在许多的系统服务。通常情况下,使用这些系统服务需要写代码来与其 Binder-exposed 的API以某种方式进行交互。然而,在某些情况下,AOSP 包括命令行实用工具来直接与某些系统服务进行交互。这些工具是非常强大,允许我们通过命令行直接进入 Android 的功能。
2.1 am
hammerhead:/ # am
usage: am [subcommand] [options]
usage: am start [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]
[--sampling INTERVAL] [-R COUNT] [-S]
[--track-allocation] [--user <USER_ID> | current] <INTENT>
am startservice [--user <USER_ID> | current] <INTENT>
am stopservice [--user <USER_ID> | current] <INTENT>
am force-stop [--user <USER_ID> | all | current] <PACKAGE>
am kill [--user <USER_ID> | all | current] <PACKAGE>
am kill-all
am broadcast [--user <USER_ID> | all | current] <INTENT>
am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]
[--user <USER_ID> | current]
[--no-window-animation] [--abi <ABI>] <COMPONENT>
am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE>
am profile stop [--user <USER_ID> current] [<PROCESS>]
am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>
am set-debug-app [-w] [--persistent] <PACKAGE>
am clear-debug-app
am set-watch-heap <PROCESS> <MEM-LIMIT>
am clear-watch-heap
am bug-report [--progress | --telephony]
am monitor [--gdb <port>]
am hang [--allow-restart]
am restart
am idle-maintenance
am screen-compat [on|off] <PACKAGE>
am package-importance <PACKAGE>
am to-uri [INTENT]
am to-intent-uri [INTENT]
am to-app-uri [INTENT]
am switch-user <USER_ID>
am start-user <USER_ID>
am unlock-user <USER_ID> [TOKEN_HEX]
am stop-user [-w] [-f] <USER_ID>
am stack start <DISPLAY_ID> <INTENT>
am stack movetask <TASK_ID> <STACK_ID> [true|false]
am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]
am stack size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]
am stack move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am stack positiontask <TASK_ID> <STACK_ID> <POSITION>
am stack list
am stack info <STACK_ID>
am stack remove <STACK_ID>
am task lock <TASK_ID>
am task lock stop
am task resizeable <TASK_ID> [0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)]
am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>
am task drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
am task size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]
am get-config
am suppress-resize-config-changes <true|false>
am set-inactive [--user <USER_ID>] <PACKAGE> true|false
am get-inactive [--user <USER_ID>] <PACKAGE>
am send-trim-memory [--user <USER_ID>] <PROCESS>
[HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]
am get-current-user
am start: start an Activity. Options are:
-D: enable debugging
-N: enable native debugging
-W: wait for launch to complete
--start-profiler <FILE>: start profiler and send results to <FILE>
--sampling INTERVAL: use sample profiling with INTERVAL microseconds
between samples (use with --start-profiler)
-P <FILE>: like above, but profiling stops when app goes idle
-R: repeat the activity launch <COUNT> times. Prior to each repeat,
the top activity will be finished.
-S: force stop the target app before starting the activity
--track-allocation: enable tracking of object allocations
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
--stack <STACK_ID>: Specify into which stack should the activity be put.
am startservice: start a Service. Options are:
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
am stopservice: stop a Service. Options are:
--user <USER_ID> | current: Specify which user to run as; if not
specified then run as the current user.
am force-stop: force stop everything associated with <PACKAGE>.
--user <USER_ID> | all | current: Specify user to force stop;
all users if not specified.
am kill: Kill all processes associated with <PACKAGE>. Only kills.
processes that are safe to kill -- that is, will not impact the user
experience.
--user <USER_ID> | all | current: Specify user whose processes to kill;
all users if not specified.
am kill-all: Kill all background processes.
am broadcast: send a broadcast Intent. Options are:
--user <USER_ID> | all | current: Specify which user to send to; if not
specified then send to all users.
--receiver-permission <PERMISSION>: Require receiver to hold permission.
am instrument: start an Instrumentation. Typically this target <COMPONENT>
is the form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there
is only one instrumentation. Options are:
-r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with
[-e perf true] to generate raw output for performance measurements.
-e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a
common form is [-e <testrunner_flag> <value>[,<value>...]].
-p <FILE>: write profiling data to <FILE>
-w: wait for instrumentation to finish before returning. Required for
test runners.
--user <USER_ID> | current: Specify user instrumentation runs in;
current user if not specified.
--no-window-animation: turn off window animations while running.
--abi <ABI>: Launch the instrumented process with the selected ABI.
This assumes that the process supports the selected ABI.
am trace-ipc: Trace IPC transactions.
start: start tracing IPC transactions.
stop: stop tracing IPC transactions and dump the results to file.
--dump-file <FILE>: Specify the file the trace should be dumped to.
am profile: start and stop profiler on a process. The given <PROCESS> argument
may be either a process name or pid. Options are:
--user <USER_ID> | current: When supplying a process name,
specify user of process to profile; uses current user if not specified.
am dumpheap: dump the heap of a process. The given <PROCESS> argument may
be either a process name or pid. Options are:
-n: dump native heap instead of managed heap
--user <USER_ID> | current: When supplying a process name,
specify user of process to dump; uses current user if not specified.
am set-debug-app: set application <PACKAGE> to debug. Options are:
-w: wait for debugger when application starts
--persistent: retain this value
am clear-debug-app: clear the previously set-debug-app.
am set-watch-heap: start monitoring pss size of <PROCESS>, if it is at or
above <HEAP-LIMIT> then a heap dump is collected for the user to report
am clear-watch-heap: clear the previously set-watch-heap.
am bug-report: request bug report generation; will launch a notification
when done to select where it should be delivered. Options are:
--progress: will launch a notification right away to show its progress.
--telephony: will dump only telephony sections.
am monitor: start monitoring for crashes or ANRs.
--gdb: start gdbserv on the given port at crash/ANR
am hang: hang the system.
--allow-restart: allow watchdog to perform normal system restart
am restart: restart the user-space system.
am idle-maintenance: perform idle maintenance now.
am screen-compat: control screen compatibility mode of <PACKAGE>.
am package-importance: print current importance of <PACKAGE>.
am to-uri: print the given Intent specification as a URI.
am to-intent-uri: print the given Intent specification as an intent: URI.
am to-app-uri: print the given Intent specification as an android-app: URI.
am switch-user: switch to put USER_ID in the foreground, starting
execution of that user if it is currently stopped.
am start-user: start USER_ID in background if it is currently stopped,
use switch-user if you want to start the user in foreground.
am stop-user: stop execution of USER_ID, not allowing it to run any
code until a later explicit start or switch to it.
-w: wait for stop-user to complete.
-f: force stop even if there are related users that cannot be stopped.
am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.
am stack movetask: move <TASK_ID> from its current stack to the top (true) or bottom (false) of <STACK_ID>.
am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.
am stack resize-docked-stack: change docked stack to <LEFT,TOP,RIGHT,BOTTOM>
and supplying temporary different task bounds indicated by
<TASK_LEFT,TOP,RIGHT,BOTTOM>
am stack size-docked-stack-test: test command for sizing docked stack by
<STEP_SIZE> increments from the side <l>eft, <t>op, <r>ight, or <b>ottom
applying the optional [DELAY_MS] between each step.
am stack move-top-activity-to-pinned-stack: moves the top activity from
<STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the
bounds of the pinned stack.
am stack positiontask: place <TASK_ID> in <STACK_ID> at <POSITION>
am stack list: list all of the activity stacks and their sizes.
am stack info: display the information about activity stack <STACK_ID>.
am stack remove: remove stack <STACK_ID>.
am task lock: bring <TASK_ID> to the front and don't allow other tasks to run.
am task lock stop: end the current task lock.
am task resizeable: change resizeable mode of <TASK_ID>.
0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)
am task resize: makes sure <TASK_ID> is in a stack with the specified bounds.
Forces the task to be resizeable and creates a stack if no existing stack
has the specified bounds.
am task drag-task-test: test command for dragging/moving <TASK_ID> by
<STEP_SIZE> increments around the screen applying the optional [DELAY_MS]
between each step.
am task size-task-test: test command for sizing <TASK_ID> by <STEP_SIZE> increments within the screen applying the optional [DELAY_MS] between
each step.
am get-config: retrieve the configuration and any recent configurations
of the device.
am suppress-resize-config-changes: suppresses configuration changes due to
user resizing an activity/task.
am set-inactive: sets the inactive state of an app.
am get-inactive: returns the inactive state of an app.
am send-trim-memory: send a memory trim event to a <PROCESS>.
am get-current-user: returns id of the current foreground user.
am supports-multiwindow: returns true if the device supports multiwindow.
<INTENT> specifications include these flags and arguments:
[-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
[-c <CATEGORY> [-c <CATEGORY>] ...]
[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--esn <EXTRA_KEY> ...]
[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
[--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
[--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]
[--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]
[--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]
[--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]
[--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
(mutiple extras passed as Integer[])
[--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]
(mutiple extras passed as List<Integer>)
[--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
(mutiple extras passed as Long[])
[--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]
(mutiple extras passed as List<Long>)
[--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
(mutiple extras passed as Float[])
[--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]
(mutiple extras passed as List<Float>)
[--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
(mutiple extras passed as String[]; to embed a comma into a string,
escape it using "\,")
[--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
(mutiple extras passed as List<String>; to embed a comma into a string,
escape it using "\,")
[--f <FLAG>]
[--grant-read-uri-permission] [--grant-write-uri-permission]
[--grant-persistable-uri-permission] [--grant-prefix-uri-permission]
[--debug-log-resolution] [--exclude-stopped-packages]
[--include-stopped-packages]
[--activity-brought-to-front] [--activity-clear-top]
[--activity-clear-when-task-reset] [--activity-exclude-from-recents]
[--activity-launched-from-history] [--activity-multiple-task]
[--activity-no-animation] [--activity-no-history]
[--activity-no-user-action] [--activity-previous-is-top]
[--activity-reorder-to-front] [--activity-reset-task-if-needed]
[--activity-single-top] [--activity-clear-task]
[--activity-task-on-home]
[--receiver-registered-only] [--receiver-replace-pending]
[--receiver-foreground]
[--selector]
[<URI> | <PACKAGE> | <COMPONENT>]
有四种可用的应用程序开发的组件类型:活动、服务、广播接收器和内容提供者。前三个类型的组件是通过意图 (Intent) 激活,am 命令个主要的特点是它拥有直接从命令行发送意图的能力。
am start -a android.intent.action.VIEW -d http://www.baidu.com
am broadcast -a com.test.mxr.TEST_BROADCAST
am start -n com.android.settings/.Settings
am命令实际上是个shell脚本:
#!/system/bin/sh
#
# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"
上面这段脚本使用 app_process 来启动 Java 代码实现 am 的功能。命令行里传递的所有的参数实际上传递给了 Java 代码。am profile 命令允许我们生成的数据通过 traceview 命令在主机上进行可视化。am monitor 命令通过活动管理器允许我们监控程序运行。这里例举了一个场景我先启动该命令然后启动几个应用:
hammerhead:/ # am monitor
** Activity starting: com.cyanogenmod.trebuchet
** Activity starting: com.android.dialer
** Activity starting: com.cyanogenmod.trebuchet
** Activity starting: com.android.messaging
** Activity starting: com.cyanogenmod.trebuchet
** Activity starting: org.lineageos.jelly
** Activity starting: com.cyanogenmod.trebuchet
这种监控能力也将让你捕获ANRS(Application Not Responding,应用程序不响应)。am命令有很强大功能,更多可看它的help信息。
2.2 pm
包管理器,跟活动管理器类似,它拥有它自己的命令行工具。
hammerhead:/ # pm
usage: pm path [--user USER_ID] PACKAGE
pm dump PACKAGE
pm install [-lrtsfd] [-i PACKAGE] [--user USER_ID] [PATH]
pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]
[--install-location 0/1/2]
[--force-uuid internal|UUID]
pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]
pm install-commit SESSION_ID
pm install-abandon SESSION_ID
pm uninstall [-k] [--user USER_ID] PACKAGE
pm set-installer PACKAGE INSTALLER
pm move-package PACKAGE [internal|UUID]
pm move-primary-storage [internal|UUID]
pm clear [--user USER_ID] PACKAGE
pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
pm default-state [--user USER_ID] PACKAGE_OR_COMPONENT
pm hide [--user USER_ID] PACKAGE_OR_COMPONENT
pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT
pm grant [--user USER_ID] PACKAGE PERMISSION
pm revoke [--user USER_ID] PACKAGE PERMISSION
pm reset-permissions
pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
pm get-app-link [--user USER_ID] PACKAGE
pm set-install-location [0/auto] [1/internal] [2/external]
pm get-install-location
pm set-permission-enforced PERMISSION [true|false]
pm trim-caches DESIRED_FREE_SPACE [internal|UUID]
pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME
pm remove-user USER_ID
pm get-max-users
NOTE: 'pm list' commands have moved! Run 'adb shell cmd package'
to display the new commands.
pm path: print the path to the .apk of the given PACKAGE.
pm dump: print system state associated with the given PACKAGE.
pm install: install a single legacy package
pm install-create: create an install session
-l: forward lock application
-r: replace existing application
-t: allow test packages
-i: specify the installer package name
-s: install application on sdcard
-f: install application on internal flash
-d: allow version code downgrade (debuggable packages only)
-p: partial application install
-g: grant all runtime permissions
-S: size in bytes of entire session
pm install-write: write a package into existing session; path may
be '-' to read from stdin
-S: size in bytes of package, required for stdin
pm install-commit: perform install of fully staged session
pm install-abandon: abandon session
pm set-installer: set installer package name
pm uninstall: removes a package from the system. Options:
-k: keep the data and cache directories around after package removal.
pm clear: deletes all data associated with a package.
pm enable, disable, disable-user, disable-until-used, default-state:
these commands change the enabled state of a given package or
component (written as "package/class").
pm grant, revoke: these commands either grant or revoke permissions
to apps. The permissions must be declared as used in the app's
manifest, be runtime permissions (protection level dangerous),
and the app targeting SDK greater than Lollipop MR1.
pm reset-permissions: revert all runtime permissions to their default state.
pm get-install-location: returns the current install location.
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media
pm set-install-location: changes the default install location.
NOTE: this is only intended for debugging; using this can cause
applications to break and other undersireable behavior.
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media
pm trim-caches: trim cache files to reach the given free space.
pm create-user: create a new user with the given USER_NAME,
printing the new user identifier of the user.
pm remove-user: remove the user with the given USER_IDENTIFIER,
deleting all data associated with that user
#列出系统内已经安装的包
pm list packages
#安装apk
pm install xx.apk
#卸载apk
pm uninstall 包名
pm同样也是启动Java代码的Shell脚本:
#!/system/bin/sh
# Script to start "pm" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/pm.jar
exec app_process $base/bin com.android.commands.pm.Pm "$@"
2.3 svc
svc 有点像瑞士军刀,提供控制多个系统服务的能力。
hammerhead:/ # svc
Available commands:
help Show information about the subcommands
power Control the power manager
data Control mobile data connectivity
wifi Control the Wi-Fi manager
usb Control Usb state
nfc Control NFC functions
请注意svc 命令的能力受限于允许和禁止指定的系统服务的行为:
hammerhead:/ # svc help power
Control the power manager
usage: svc power stayon [true|false|usb|ac|wireless]
Set the 'keep awake while plugged in' setting.
svc power reboot [reason]
Perform a runtime shutdown and reboot device with specified reason.
svc power shutdown
Perform a runtime shutdown and power off the device.
hammerhead:/ # svc help data
Control mobile data connectivity
usage: svc data [enable|disable]
Turn mobile data on or off.
hammerhead:/ # svc help wifi
Control the Wi-Fi manager
usage: svc wifi [enable|disable]
Turn Wi-Fi on or off.
2.4 ime
ime 指令让你与输人法系统服务通信来控制可用输人法的系统使用。ime命令在一个脚本中使用app_process 启动Java代码。正如svc命令、ime 命令是一个值得记住、但可能不经常使用的命令。
# Script to start "pm" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/ime.jar
exec app_process $base/bin com.android.commands.ime.Ime "$@"
hammerhead:/ # ime
usage: ime list [-a] [-s]
ime enable ID
ime disable ID
ime set ID
The list command prints all enabled input methods. Use
the -a option to see all input methods. Use
the -s option to see only a single summary line of each.
The enable command allows the given input method ID to be used.
The disable command disallows the given input method ID from use.
The set command switches to the given input method ID.
2.5 input
input 连接到窗口管理系统服务并将文本或按键事件注人系统。
# Script to start "input" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/input.jar
exec app_process $base/bin com.android.commands.input.Input "$@"
hammerhead:/ # input
Usage: input [<source>] <command> [<arg>...]
The sources are:
keyboard
mouse
joystick
touchnavigation
touchpad
trackball
dpad
stylus
gesture
gamepad
touchscreen
The commands and default sources are:
text <string> (Default: touchscreen)
keyevent [--longpress] <key code number or name> ... (Default: keyboard)
tap <x> <y> (Default: touchscreen)
swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
press (Default: trackball)
roll <dx> <dy> (Default: trackball)
frameworks/base/core/java/android/view/KeyEvent.java中有各个按键编号:
public class KeyEvent extends InputEvent implements Parcelable {
/** Key code constant: Unknown key code. */
public static final int KEYCODE_UNKNOWN = 0;
/** Key code constant: Soft Left key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom left
* of the display. */
public static final int KEYCODE_SOFT_LEFT = 1;
/** Key code constant: Soft Right key.
* Usually situated below the display on phones and used as a multi-function
* feature key for selecting a software defined function shown on the bottom right
* of the display. */
public static final int KEYCODE_SOFT_RIGHT = 2;
/** Key code constant: Home key.
* This key is handled by the framework and is never delivered to applications. */
public static final int KEYCODE_HOME = 3;
/** Key code constant: Back key. */
public static final int KEYCODE_BACK = 4;
/** Key code constant: Call key. */
public static final int KEYCODE_CALL = 5;
/** Key code constant: End Call key. */
public static final int KEYCODE_ENDCALL = 6;
/** Key code constant: '0' key. */
public static final int KEYCODE_0 = 7;
/** Key code constant: '1' key. */
public static final int KEYCODE_1 = 8;
/** Key code constant: '2' key. */
public static final int KEYCODE_2 = 9;
/** Key code constant: '3' key. */
public static final int KEYCODE_3 = 10;
/** Key code constant: '4' key. */
public static final int KEYCODE_4 = 11;
......
2.6 monkey
monkey 命令可以用于提供随机而又可重复的输人给你的应用程序。例如,这个命令将50 个伪随机输人到浏览器的应用程序,可通过如下命令实现:
monkey -p com.android.browser -v 50
还可以实现更多功能:
hammerhead:/ # monkey
usage: monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]
[-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]
[--ignore-crashes] [--ignore-timeouts]
[--ignore-security-exceptions]
[--monitor-native-crashes] [--ignore-native-crashes]
[--kill-process-after-error] [--hprof]
[--pct-touch PERCENT] [--pct-motion PERCENT]
[--pct-trackball PERCENT] [--pct-syskeys PERCENT]
[--pct-nav PERCENT] [--pct-majornav PERCENT]
[--pct-appswitch PERCENT] [--pct-flip PERCENT]
[--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]
[--pct-permission PERCENT]
[--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]
[--pkg-whitelist-file PACKAGE_WHITELIST_FILE]
[--wait-dbg] [--dbg-no-events]
[--setup scriptfile] [-f scriptfile [-f scriptfile] ...]
[--port port]
[-s SEED] [-v [-v] ...]
[--throttle MILLISEC] [--randomize-throttle]
[--profile-wait MILLISEC]
[--device-sleep-time MILLISEC]
[--randomize-script]
[--script-log]
[--bugreport]
[--periodic-bugreport]
[--permission-target-system]
COUNT
还可以为 monkey 提供一个脚本运行一组预定义的输入而不是提供随机输人。这是用于开发、测试、现场诊断的一个非常有用的功能。比如写一个名为monkey_script的脚本。
type= raw events
count= 10
speed= 1.0
start data >>
Tap(942,1472);
Drag(1064,1858,875,933,1);
Tap(334,882);
Tap(1058,950);
Tap(991,339);
Tap(464,1195);
Tap(350,1391);
Drag(118,1578,1018,298,1);
Tap(572,426);
Drag(575,1387,80,1531,1);
Tap(253,1788);
Tap(713,887);
Tap(795,721);
Tap(199,1513);
Drag(877,559,854,1440,1);
Drag(125,1039,70,1413,1);
Tap(766,120);
Tap(783,1646);
Drag(866,1173,84,1075,1);
Tap(1018,157);
Drag(642,1012,893,1135,1);
Tap(1004,1565);
Drag(927,1731,201,190,1);
Tap(106,1106);
Tap(824,1659);
Tap(741,1780);
Drag(12,1174,847,1914,1);
Tap(322,1290);
Drag(332,1645,914,104,1);
按照这个脚本命令执行monkey:
monkey -f monkey_script 1
2.7 bmgr
Android 拥有了备份功能,允许用户将他们拥有的数据备份到云中,以便以后如果丢失或更换它们的设备后,还能对数据进行还原。有一个工具 bmgr,允许你从命令行控制备份管理系统服务的行为。
hammerhead:/ # bmgr
usage: bmgr [backup|restore|list|transport|run]
bmgr backup PACKAGE
bmgr enable BOOL
bmgr enabled
bmgr list transports
bmgr list sets
bmgr transport WHICH
bmgr restore TOKEN
bmgr restore TOKEN PACKAGE...
bmgr restore PACKAGE
bmgr run
bmgr wipe TRANSPORT PACKAGE
bmgr fullbackup PACKAGE...
bmgr backupnow --all|PACKAGE...
3 Dalvik工具
3.1 dalvikvm
我们知道如何通过 am 命令来发送事件,因而触发新的应用程序启动,这些应用程序中的每一个都有自己的 Zygote-forked Dalvik 实例。我们也看到app_process 命令是如何使用Android 的运行时刻(Runtime)来启动Java 编码的命令行工具的。然而,某些情况下,你可能想放弃所有的 Android 特定的层,并直接参与到 Dalvik 中。可以通过以下命令:
hammerhead:/ # dalvikvm -help
dalvikvm: [options] class [argument ...]
The following standard options are supported:
-classpath classpath (-cp classpath)
-Dproperty=value
-verbose:tag ('gc', 'jit', 'jni', or 'class')
-showversion
-help
-agentlib:jdwp=options
-agentpath:library_path=options (Experimental feature, requires -Xexperimental:agent, some features might not be supported)
The following extended options are supported:
-Xrunjdwp:<options>
-Xbootclasspath:bootclasspath
-Xcheck:tag (e.g. 'jni')
-XmsN (min heap, must be multiple of 1K, >= 1MB)
-XmxN (max heap, must be multiple of 1K, >= 2MB)
-XssN (stack size)
-Xint
The following Dalvik options are supported:
-Xzygote
-Xjnitrace:substring (eg NativeClass or nativeMethod)
-Xstacktracefile:<filename>
-Xgc:[no]preverify
-Xgc:[no]postverify
-XX:HeapGrowthLimit=N
-XX:HeapMinFree=N
-XX:HeapMaxFree=N
-XX:NonMovingSpaceCapacity=N
-XX:HeapTargetUtilization=doublevalue
-XX:ForegroundHeapGrowthMultiplier=doublevalue
-XX:LowMemoryMode
-Xprofile:{threadcpuclock,wallclock,dualclock}
-Xjitthreshold:integervalue
The following unique to ART options are supported:
-Xgc:[no]preverify_rosalloc
-Xgc:[no]postsweepingverify_rosalloc
-Xgc:[no]postverify_rosalloc
-Xgc:[no]presweepingverify
-Ximage:filename
-Xbootclasspath-locations:bootclasspath
(override the dex locations of the -Xbootclasspath files)
-XX:+DisableExplicitGC
-XX:ParallelGCThreads=integervalue
-XX:ConcGCThreads=integervalue
-XX:MaxSpinsBeforeThinLockInflation=integervalue
-XX:LongPauseLogThreshold=integervalue
-XX:LongGCLogThreshold=integervalue
-XX:ThreadSuspendTimeout=integervalue
-XX:DumpGCPerformanceOnShutdown
-XX:DumpJITInfoOnShutdown
-XX:IgnoreMaxFootprint
-XX:UseTLAB
-XX:BackgroundGC=none
-XX:LargeObjectSpace={disabled,map,freelist}
-XX:LargeObjectThreshold=N
-XX:DumpNativeStackOnSigQuit=booleanvalue
-XX:MadviseRandomAccess:booleanvalue
-XX:SlowDebug={false,true}
-Xmethod-trace
-Xmethod-trace-file:filename -Xmethod-trace-file-size:integervalue
-Xps-min-save-period-ms:integervalue
-Xps-save-resolved-classes-delay-ms:integervalue
-Xps-hot-startup-method-samples:integervalue
-Xps-min-methods-to-save:integervalue
-Xps-min-classes-to-save:integervalue
-Xps-min-notification-before-wake:integervalue
-Xps-max-notification-before-wake:integervalue
-Xps-profile-path:file-path
-Xcompiler:filename
-Xcompiler-option dex2oat-option
-Ximage-compiler-option dex2oat-option
-Xpatchoat:filename
-Xusejit:booleanvalue
-Xjitinitialsize:N
-Xjitmaxsize:N
-Xjitwarmupthreshold:integervalue
-Xjitosrthreshold:integervalue
-Xjitprithreadweight:integervalue
-X[no]relocate
-X[no]dex2oat (Whether to invoke dex2oat on the application)
-X[no]image-dex2oat (Whether to create and use a boot image)
-Xno-dex-file-fallback (Don't fall back to dex files without oat files)
-Xplugin:<library.so> (Load a runtime plugin, requires -Xexperimental:runtime-plugins)
-Xexperimental:runtime-plugins(Enable new and experimental agent support)
-Xexperimental:agents(Enable new and experimental agent support)
The following previously supported Dalvik options are ignored:
-ea[:<package name>... |:<class name>]
-da[:<package name>... |:<class name>]
(-enableassertions, -disableassertions)
-esa
-dsa
(-enablesystemassertions, -disablesystemassertions)
-Xverify:{none,remote,all,softfail}
-Xrs
-Xint:portable, -Xint:fast, -Xint:jit
-Xdexopt:{none,verified,all,full}
-Xnoquithandler
-Xjniopts:{warnonly,forcecopy}
-Xjnigreflimit:integervalue
-Xgc:[no]precise
-Xgc:[no]verifycardtable
-X[no]genregmap
-Xverifyopt:[no]checkmon
-Xcheckdexsum
-Xincludeselectedop
-Xjitop:hexopvalue[-endvalue][,hexopvalue[-endvalue]]*
-Xincludeselectedmethod
-Xjitblocking
-Xjitmethod:signature[,signature]* (eg Ljava/lang/String\;replace)
-Xjitclass:classname[,classname]*
-Xjitcodecachesize:N
-Xjitoffset:offset[,offset]
-Xjitconfig:filename
-Xjitcheckcg
-Xjitverbose
-Xjitprofile
-Xjitdisableopt
-Xjitsuspendpoll
-XX:mainThreadStackSize=N
dalvikvm 实际上是一个原始的没有连接到任何“Android”上的 Dalvik 虚拟机。它不依赖于 Zygote,同时它也不包含 Android 的运行时库。它只是启动一个虚拟机来运行你提供的所有类或JAR 文件。实际上 AOSP 本身并不经常使用它,可能是因为在AOSP中没有太多不运行在“Android”上下文中的情况。
3.2 dexdump
如果你想要反向开发Android 应用程序或者JAR 文件,你可以通过dexdump 命令实现:
hammerhead:/ # dexdump
dexdump: no file specified
Copyright (C) 2007 The Android Open Source Project
dexdump: [-c] [-d] [-f] [-h] [-i] [-l layout] [-m] [-t tempfile] dexfile...
-c : verify checksum and exit
-d : disassemble code sections
-f : display summary information from file header
-h : display file header details
-i : ignore checksum failures
-l : output layout, either 'plain' or 'xml'
-m : dump register maps (and nothing else)
-t : temp file name (defaults to /sdcard/dex-temp-*)