Android 系统的分区和文件系统(5)- Android Framework层上的工具和命令

声明

  • 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-*)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馬佩德罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值