Android的ADB

ADB

Adb的全称为Android Debug Bridge:android调试桥梁
Android的初衷是用adb这样的一个工具来协助开发人员在开发android应用的过程中更快更好的调试apk,因此adb具有安装卸载apk、拷贝推送文件、查看设备硬件信息、查看应用程序占用资源、在设备执行shell命令等功能;
我们可以在android sdk安装目录的platform-tools目录下找到adb工具。在window下需要配置adb环境变量,读者自行搜索博客配置(配置好可以在cmd中adb命令查看),在Ubuntu可以sudo apt-get install adb,安装好后adb version查看adb 版本。

ADB 问题

  1. 在后续使用adb命令时出现
powershell error: no devices/emulators found

时,是没有找到设备或模拟器导致的。

① 检查是否连上了设备或者打开了模拟器
②检查设备或模拟器是否打开了开发者模式,读者自行搜索如何开启。
③adb功能异常,重启adb
        (1)把adb服务杀死:adb kill-server
        (2)重启adb服务:adb reconnect
         注:如果使用的不是真机而是模拟器,需要进行连接操作,即运行adb connect 127.0.0.1:62001 其中62001为模拟器所使用的端口号。
  1. cat:xxx Permission denied
    权限不足问题,为了获得执行权限,借助chmod指令修改文件权限即可。可以使用访问Android
  2. adb devices : no permissions问题
    设置usb权限
    因为ubuntu这样的系统都是默认以非root身份在运行的,要使用usb调试,需要sudo支持。
    首先,在未连接Android设备的情况下,查看一下Linux下的usb,类似如下
# 运行lsusb命令

lsusb

# 结果

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 413c:2113 Dell Computer Corp. 
Bus 001 Device 002: ID 413c:301a Dell Computer Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

然后,打开android设备的usb调试模式,连接到Linux电脑上,运行

# 运行lsusb指令,查看设备信息

lsusb

# 显示结果如下

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 413c:2113 Dell Computer Corp. 
Bus 001 Device 002: ID 413c:301a Dell Computer Corp. 
Bus 001 Device 083: ID 05c6:9110 # 此条新增的条目,则是新连接的android设备
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

如上则可以查看到新连接的Android设备信息,注意其ID号,这里是05c6和9110
然后cd /etc/udev/rules.d/目录下,查看.rules文件

cd /etc/udev/rules.d/
ls

# 结果如下,名称可能不同,如果没有则新建一个:sudo touch 51-android.rules

51-android.rules

# 然后编辑该文件

sudo vim 51-android.rules

# 然后进入vim,按下i 键会进行插入模式,加入如下代码,然后按下Esc键,键盘输入:wq 退出文件并保存对文件的修改

SUBSYSTEM=="usb",ATTRS{idVendor}=="05c6",ATTRS{idProduct}=="9110",MODE="0666"

这里05c6和9110则分别是上一步中查看到的android设备的额ID信息,MODE应该是表示权限。

运行命令,重启udev:

sudo chmod a+rx /etc/udev/rules.d/51-android.rules  //或者sudo nautilus 可视化权限修改
sudo service udev restart

(很重要)拔掉usb重新连上再执行
重新启动adb server:

sudo adb kill-server
sudo adb start-server
adb devices
# 若要需要root权限进入Android设备的shell,可以运行
adb root
adb remount
adb shell

(拔插usb,使用以下命令可以实时监视系统信息sudo tail -f /var/log/messages
ubuntu 敲 adb devices 设备列表为空,但lsusb可以查看到PID与VID。此时可以sudo gedit ~/.android/adb_usb.ini 编辑该文件,加入0x0bb4 后执行下面命令

sudo service udev restart 
android update adb

更新服务)

简单方法:

sudo adb kill-server
sudo adb devices

ADB 命令

adb 命令的基本语法:adb [-d|-e|-s ]

  • 如果只有一个设备/模拟器连接时,可以省略掉 [-d|-e|-s ] 这一部分,直接使用 adb 。
  • 如果有多个设备/模拟器连接,则需要为命令指定目标设备。
参数含义
-d指定当前唯一通过 USB 连接的 Android 设备为命令目标
-e指定当前唯一运行的模拟器为命令目标
-s 指定相应 serialNumber 号的设备/模拟器为命令目标(adb devices前面部分)例如:adb -s 序列号 shell

adb devices查看已经连接的设备
输出格式为 [serialNumber] [state],serialNumber 即我们常说的 SN,state 有如下几种:

  • offline —— 表示设备未连接成功或无响应。
  • device —— 设备已连接。注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到adb,但启动完毕后系统才处于可操作状态。
  • no device —— 没有设备/模拟器连接。

adb connect <device-ip-address>通过 IP 地址连接设备。(需要连接USB数据线,确认 Android 设备与电脑连接到了同一个 WiFi)
不需要连接USB数据线的情况下(需要 root 权限):
在 Android 设备上安装一个终端模拟器。
已经安装过的设备可以跳过此步。推荐使用的终端模拟器下载地址是:Terminal Emulator for Android Downloads
将 Android 设备与要运行 adb 的电脑连接到同一个局域网,比如连到同一个 WiFi。
打开 Android 设备上的终端模拟器,在里面依次运行命令:

su
setprop service.adb.tcp.port 5555

然后就是adb connect <device-ip-address>,出现connected to :5555 这样的输出则表示连接成功。
(有的设备,可能需要重启 adbd 服务,在设备的终端模拟器上运行:restart adbd
如果 restart 无效,尝试以下命令:stop adbd和start adbd
adb disconnect <device-ip-address>断开无线连接
adb get-serialno获取手机序列号
adb shell getprop ro.product.model查看手机设备型号
adb shell wm size查看手机分辨率
adb shell cat /sys/class/net/wlan0/address获取手机的mac地址
adb logcat [<option>] ... [<filter-spec>] ...查看日志

adb log包含了:日期、时间、PID、TID、日志级别、标签、日志内容。
PID:可以看成app运行时,在系统中的唯一的一个标识。
TID:PID可以对应多个TID,主要是由于支持多线程。每个线程对应一个TID。
日志级别:Android Log类源码中,日志有6个级别priority。分别是:
V(Verbose 明细,最低级别)、D(Debug 调试)、I(Info 信息)、W(Warn 警告)、E(Error 错误)、 S(Silent最高,啥也不输出)。
标签:开发中,标记日志的一个属性。如,使用类名,表示是哪个类里输出的日志。

小知识:
pid 是process进程id , uid 是user 用户id; 如果 你 是root,那么你的uid就是0,0为最高权限;
每一个不同的程序都能有一个UId,但是一个应用里面可以有多个PId; 一个用户可以打开多个进程(Pid),并且这些进程的uid是一样的;
一个pid对应一个进程,每次打开时系统都会赋予不同的pid,但是uid是当你安装Apk时,系统赋予的,是不变的,除非你卸载了重装,又会赋予一个Uid;

Tid(thead id)可以理解为线程的Id,这个更容易理解

  • 按级别过滤日志 Android 的日志分为如下几个优先级(priority):

    V —— Verbose(最低,输出得最多)
    D —— Debug I —— Info
    W —— Warning
    E —— Error
    F—— Fatal
    S —— Silent(最高,啥也不输出) 
    
  • 按 tag 和级别过滤日志:
    可以由多个 [:priority] 组成。
    比如,命令:adb logcat ActivityManager:I MyApp:D *:S
    表示输出 tag ActivityManager 的 Info 以上级别日志,输出 tag MyApp 的 Debug
    以上级别日志,及其它 tag 的 Silent 级别日志(即屏蔽其它 tag 日志)。

  • 日志格式 可以用 adb logcat -v 选项指定日志输出格式。 日志支持按以下几种 :
    1.brief
    默认格式。格式为:<priority>/<tag>(<pid>): <message>
    示例:D/HeadsetStateMachine( 1785): Disconnected process message: 10,size: 0
    2.process
    格式为:<priority>(<pid>) <message>
    示例:D( 1785) Disconnected process message: 10, size: 0 (HeadsetStateMachine)
    3.tag
    格式为:<priority>/<tag>: <message>
    示例:D/HeadsetStateMachine: Disconnected process message: 10, size: 0
    4. raw
    格式为:<message>
    示例:Disconnected process message: 10, size: 0
    5. time
    格式为: <datetime> <priority>/<tag>(<pid>): <message>
    示例:08-28 22:39:39.974 D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0
    6. threadtime
    格式为:<datetime> <pid> <tid> <priority> <tag>: <message>
    示例:08-28 22:39:39.974 1785 1832 D HeadsetStateMachine: Disconnected process message: 10, size: 0
    7. long
    格式为: [ <datetime> <pid>:<tid> <priority>/<tag> ] <message>
    示例:[ 08-28 22:39:39.974 1785: 1832 D/HeadsetStateMachine ] Disconnected process message: 10, size: 0
    8.指定格式可与上面的过滤同时使用。比如:adb logcat -v long ActivityManager:I *:S
    可以结合grep命令过滤adb logcat | grep -E '^[VDE]/(TAG1|TAG2)'grep教程

adb logcat -v time >D:\log.txt//将日志保存到电脑固定的位置,比如D:\log.txt

adb shell dumpsys battery查看电池信息
adb shell ps查看进程
adb shell top查看cpu使用情况
adb install [-lrtsdg] [apk文件的路径]apk文件需要放到你命令执行的文件夹下,或者写上apk的绝对路径

参数含义
-l将应用安装到保护目录 /mnt/asec
-r允许覆盖安装
-t允许安装 AndroidManifest.xml 里 application 指定 android:testOnly=“true” 的应用
-s将应用安装到 sdcard
-d允许降级覆盖安装
-g授予所有运行时权限
adb -s [设备号] install [apk文件的路径]多个设备安装apk
adb uninstall [apk文件的路径]普通卸载
adb uninstall -k [apk文件的路径]卸载但是保留数据

adb shell dumpsys package com.ss.android.ugc.aweme | findstr activity获取某个应用包名的启动入口

adb shell screencap [保存路径]屏幕截图
adb shell screenrecord [保存路径]录制视频
adb push 文件名 手机端SDCard路径上传文件到手机
adb pull [手机上文件路径] [电脑路径]从手机端下载文件
adb shell input tap x坐标轴 y坐标轴模拟屏幕点击事件
adb shell input swipe 开始x轴 开始y轴 结束x轴 结束y轴 过程持续时间毫秒模拟手势滑动事件
adb shell input keyevent [key值]模拟点按键盘按钮
db shell input text [字符串信息]向屏幕输入一些信息(%s是空格)
adb shell am broadcast -a "action name"发送广播
adb shell am start -a [浏览器包名] -d [网址]使用自带浏览器打开网页
adb vivoroot获取手机root权限
adb remount连接不稳定时需要挂载
adb reboot正常重启
adb reboot recovery重启手机到recovery
adb reboot bootloader重启到bootloader界面
adb kill-server关闭adb服务
adb start-server启动adb服务(一般无需手动执行此命令,在运行 adb 命令时若发现 adb server 没有启动会自动调起。)
adb -P <port> start-server指定 adb server 的网络端口。默认端口为 5037。

以 root 权限运行 adbd

adb 的运行原理是 PC 端的 adb server 与手机端的守护进程 adbd 建立连接,然后 PC 端的 adb client 通过 adb server 转发命令,adbd 接收命令后解析运行。

所以如果 adbd 以普通权限执行,有些需要 root 权限才能执行的命令无法直接用 adb xxx 执行。这时可以 adb shell 然后 su 后执行命令,也可以让 adbd 以 root 权限执行,这个就能随意执行高权限命令了。命令adb root,正常输出为restarting adbd as root。再运行 adb shell,命令行提示符就会变成 # 。
有些手机 root 后也无法通过 adb root 命令让 adbd 以 root 权限执行,比如三星的部分机型,会提示 adbd cannot run as root in production builds,此时可以先安装 adbd Insecure,然后 adb root 试试。

相应地,如果要恢复 adbd 为非 root 权限的话,可以使用 adb unroot 命令。

adb详细

pm

常用

list packages
list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]查看手机上所有安装的app包名; 可选地,只有 FILTER 中的那些。
即在 adb shell pm list packages 的基础上可以加一些参数进行过滤查看不同的列表,支持的过滤参数如下:

参数显示列表
所有应用
-f显示应用关联的 apk 文件
-a所有已知包(但不包括 APEX)
-d只显示 禁用disabled 的应用
-e只显示 启用enabled 的应用
-s只显示 系统system 应用
-3只显示第三方应用
-i显示应用的 installer
-l忽略(用于与旧版本兼容)
-U同时显示包的 UID
-u包含已卸载应用
–show-versioncode也显示版本代码
–apex-only只显示 APEX 包
–uid UID过滤以仅显示具有给定 UID 的包
–user USER_ID只列出属于给定用户的包
<FILTER>包名包含 <FILTER> 字符串
可以带上包名
14:45:12[~]~$  adb shell pm list packages com.android.chrome
package:com.android.chrome
14:45:23[~]~$  adb shell pm list packages -f com.android.chrome
package:/product/app/Chrome/Chrome.apk=com.android.chrome
14:49:17[~]~$  adb shell pm list packages -i com.android.chrome
package:com.android.chrome  installer=null

所有

14:56:21[~]~$  adb shell pm help
Package manager (package) commands:包管理器(包)命令:
  help
    Print this help text.

  path [--user USER_ID] PACKAGE
		打印给定包的 .apk 的路径。

  dump PACKAGE
    打印与给定 PACKAGE 关联的各种系统状态。很多

  has-feature FEATURE_NAME [version]
    当系统有 FEATURE_NAME 时打印 true 并返回退出状态 0,否则打印 false 并返回退出状态 1

  list features
    打印系统的所有功能。
  list instrumentation [-f] [TARGET-PACKAGE]
    打印所有测试包; (可选)仅针对 TARGET-PACKAGE 的那些
    选项: -f:转储包含测试包的.apk文件的名称
  list libraries
    打印所有系统库。
  list permission-groups
    打印所有已知的权限组。
  list permissions [-g] [-f] [-d] [-u] [GROUP]
    打印所有已知权限; 可选地,只有 GROUP 中的那些。 选项是:
       -g:按组组织
       -f:打印所有信息
       -s:简短摘要
       -d:只列出危险权限
       -u:仅列出用户将看到的权限
  list staged-sessions [--only-ready] [--only-sessionid] [--only-parent]
    打印所有分阶段的会话。
      --only-ready: 只显示准备好的分阶段会话
      --only-sessionid: 只显示每个会话的 sessionId
      --only-parent: 隐藏所有子会话
  list users
    Prints all users.

  resolve-activity [--brief] [--components] [--query-flags FLAGS] [--user USER_ID] INTENT
    打印解析为给定意图的活动。

  query-activities [--brief] [--components] [--query-flags FLAGS] [--user USER_ID] INTENT
    打印可以处理给定意图的所有活动。
  query-services [--brief] [--components] [--query-flags FLAGS] [--user USER_ID] INTENT
    打印所有可以处理给定意图的服务。
  query-receivers [--brief] [--components] [--query-flags FLAGS] [--user USER_ID] INTENT
    打印所有可以处理给定意图的广播接收器。

  install [-rtfdgw] [-i PACKAGE] [--user USER_ID|all|current] [-p INHERIT_PACKAGE] [--install-location 0/1/2] [--install-reason 0/1/2/3/4] [--originating-uri URI] [--referrer URI] [--abi ABI_NAME] [--force-sdk]
       [--preload] [--instant] [--full] [--dont-kill] [--enable-rollback] [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex] [--staged-ready-timeout TIMEOUT] [PATH [SPLIT...]|-]
安装应用程序。必须提供要安装的 apk 数据,或者作为要从标准输入读取的文件路径或“-”。选项是:
      -R:不允许替换现有应用程序
      -t:允许测试包
      -i:指定拥有应用程序的安装程序的包名称
      -f:在内部闪存上安装应用程序
      -d:允许版本代码降级(仅限可调试包)
      -p:部分应用程序安装(在现有 pkg​​ 之上的新拆分)
      -g:授予所有运行时权限
      -S:以字节为单位的包大小,stdin 需要
      --user:在给定用户下安装。
      --dont-kill:安装一个新的功能拆分,不要杀死正在运行的应用程序
      --restrict-permissions:安装时不要将受限权限列入白名单
      --originating-uri:设置下载应用程序的URI
      --referrer:设置启动应用程序安装的 URI
      --pkg:指定正在安装的应用程序的预期包名称
      --abi:覆盖平台的默认ABI
      --instant:使应用程序作为临时安装应用程序安装
      --full:使应用程序作为非临时完整应用程序安装
      --install-location:强制安装位置: 0=自动,1=仅内部,2=首选外部
      --install-reason: 指明为什么要安装应用程序: 0=未知,1=管理策略,2=设备恢复,3=设备设置,4=用户请求
      --force-uuid:强制安装到具有给定 UUID 的磁盘卷
      --apex:安装 .apex 文件,而不是 .apk
      --staged-ready-timeout:默认情况下,在执行分阶段安装时,分阶段会话等待 60000 毫秒以完成重启前验证。此标志用于更改等待时间。您可以通过将 TIMEOUT 指定为“0”来跳过等待时间
  install-existing [--user USER_ID|all|current] [--instant] [--full] [--wait] [--restrict-permissions] PACKAGE
		为新用户安装现有应用程序。 选项是:
       --user:为给定用户安装。
       --instant:作为免安装应用安装
       --full:作为完整应用安装
       --wait:等到包安装完毕
       --restrict-permissions:不将受限权限列入白名单
  install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current] [-p INHERIT_PACKAGE] [--install-location 0/1/2] [--install-reason 0/1/2/3/4] [--originating-uri URI]
       [--referrer URI] [--abi ABI_NAME] [--force-sdk] [--preload] [--instant] [--full] [--dont-kill] [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES] [--multi-package] [--staged]
    与“安装”类似,但会启动安装会话。使用“安装写入”将数据推送到会话中,然后“install-commit”完成。
  install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]
    将 apk 写入给定的安装会话。如果路径是'-',数据将从标准输入读取。选项是:
      -S:以字节为单位的包大小,stdin 需要
  install-remove SESSION_ID SPLIT...
    在给定的安装session中将 SPLIT 标记为已删除。
  install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs
    将一个或多个session IDs 添加到multi-package session。
  install-commit SESSION_ID
    提交给定的active install session,安装应用程序。
  install-abandon SESSION_ID
    删除给定的active install session。

  set-install-location LOCATION
    更改默认安装位置。注意这仅用于调试;使用它可能会导致应用程序中断和其他不良行为。位置是以下之一:
    0 [auto]:让系统决定最佳位置
    1 [内部]:安装在内部设备存储上
    2 [外部]:安装在外部媒体上
  get-install-location
    根据 set-install-location 返回当前安装位置:0、1 或 2。

  move-package PACKAGE [internal|UUID] 移动包
  move-primary-storage [internal|UUID] 移动主存储

  uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE]
       PACKAGE [SPLIT...]
    从系统中删除给定的包名称。如果未指定 SPLIT 名称,则可能会删除整个应用程序,否则将仅删除给定应用程序的拆分。选项是:
      -k:删除软件包后保留数据和缓存目录。
      --user:从给定用户中删除应用程序。
      --versionCode:仅当应用程序具有给定的版本代码时才卸载。

  clear [--user USER_ID] PACKAGE
    删除与包关联的所有数据。

  enable [--user USER_ID] PACKAGE_OR_COMPONENT
  disable [--user USER_ID] PACKAGE_OR_COMPONENT
  disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
  disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
  default-state [--user USER_ID] PACKAGE_OR_COMPONENT
    这些命令更改给定包或组件的启用状态(写为“package/class”)。

  hide [--user USER_ID] PACKAGE_OR_COMPONENT
  unhide [--user USER_ID] PACKAGE_OR_COMPONENT
  suspend [--user USER_ID] PACKAGE [PACKAGE...]
    挂起指定的包(作为用户)。
  unsuspend [--user USER_ID] PACKAGE [PACKAGE...]
    取消挂起指定的包(作为用户)。

  set-distracting-restriction [--user USER_ID] [--flag FLAG ...] PACKAGE [PACKAGE...]
    将指定的限制标志设置为给定的包(对于用户)。标志是:
      hide-notifications:隐藏此包中的通知
      hide-from-suggestions:从建议中隐藏这个包
        (通过发射器等)
    任何现有的标志都会被覆盖,这也意味着如果没有标志
    指定,则所有现有标志将被清除。

  grant [--user USER_ID] PACKAGE PERMISSION  授予 [--user USER_ID] 包权限
  revoke [--user USER_ID] PACKAGE PERMISSION  撤销 [--user USER_ID] 包权限
    这些命令可以授予或撤销应用程序的权限。权限必须声明为在应用程序清单中使用,是运行时权限(保护级别危险),并且应用程序目标 SDK 大于 Lollipop MR1。

  reset-permissions
    将所有运行时权限恢复为其默认状态。
  set-permission-enforced PERMISSION [true|false] 设置权限强制执行权限 [true|false]
  get-privapp-permissions TARGET-PACKAGE
    打印包的所有特权权限。
  get-privapp-deny-permissions TARGET-PACKAGE
    打印包被拒绝的所有特权权限。
  get-oem-permissions TARGET-PACKAGE
    打印包的所有 OEM 权限。

  trim-caches DESIRED_FREE_SPACE [internal|UUID]
    修剪缓存文件以达到给定的可用空间。

  list users
    列出当前用户。
  create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] [--pre-create-only] [--user-type USER_TYPE] USER_NAME
    使用给定的 USER_NAME 创建一个新用户,打印用户的新用户标识符。
    USER_TYPE 是用户类型的名称,例如android.os.usertype.profile.MANAGED。
      如果未指定,则默认用户类型为 android.os.usertype.full.SECONDARY。
      --managed is 简写 for '--user-type android.os.usertype.profile.MANAGED'.
      --restricted is 简写 for '--user-type android.os.usertype.full.RESTRICTED'.
      --guest is 简写 for '--user-type android.os.usertype.full.GUEST'.
  remove-user [--set-ephemeral-if-in-use] USER_ID
    删除具有给定 USER_IDENTIFIER 的用户,删除与该用户关联的所有数据。
      --set-ephemeral-if-in-use: 如果用户当前正在运行,因此无法立即删除,则将用户标记为临时用户,以便在可能的情况下自动删除(在用户切换或重新启动后)
  set-user-restriction [--user USER_ID] RESTRICTION VALUE 设置用户限制 [--user USER_ID] 限制值
  get-max-users  获取最大用户
  get-max-running-users  获取最大运行用户

  compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]
          [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)
    如果为“-a”,则触发 TARGET-PACKAGE 或所有包的编译。选项是:
      -a:编译所有包
      -c:编译前清除配置文件数据
      -f:即使不需要也强制编译
      -m:选择编译模式
          MODE 是 dex2oat 编译器过滤器之一:assume-verified | extract | verify | quicken | space-profile | space | speed-profile | speed | everything
      -r: 选择编译原因 原因是以下之一:
            first-boot | boot-after-ota | post-boot | install | install-fast | install-bulk | install-bulk-secondary | install-bulk-downgraded | install-bulk-secondary-downgraded | bg-dexopt | ab-ota | inactive | cmdline | shared
      --reset: 将包恢复到安装后的状态
      --check-prof (true | false): 做 dexopt 时查看配置文件?
      --secondary-dex: 编译app二级dex文件
      --split SPLIT: 仅编译给定的拆分名称
      --compile-layouts: 编译布局资源以加快通货膨胀

  force-dex-opt PACKAGE
    强制立即执行给定 PACKAGE 的 dex opt。

  bg-dexopt-job
    立即执行后台优化。
    请注意,该命令仅运行后台优化器逻辑。它可能与实际作业重叠,但作业调度程序将无法取消它。即使设备未处于空闲维护模式,它也会运行。

  reconcile-secondary-dex-files TARGET-PACKAGE
    将包二级 dex 文件与生成的 oat 文件协调。

  dump-profiles TARGET-PACKAGE
    将method/class配置文件转储到/data/misc/profman/TARGET-PACKAGE.txt

  snapshot-profile TARGET-PACKAGE [--code-path path]
    拍摄包配置文件的快照 /data/misc/profman/TARGET-PACKAGE[-code-path].prof 如果 TARGET-PACKAGE=android 它将拍摄启动映像的快照

  set-home-activity [--user USER_ID] TARGET-COMPONENT
    设置默认的 home activity(又名启动器)。
    TARGET-COMPONENT 可以是包名 (com.package.my) 或完整的组件(com.package.my/component.name)。然而,只有包名很重要:实际使用的组件将由包自动确定。

  set-installer PACKAGE INSTALLER
    设置安装包名称
  get-instantapp-resolver
    返回作为当前免安装应用安装程序的组件的名称。

  set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]
    使用给定的警告消息将应用程序标记为有害。
  get-harmful-app-warning [--user <USER_ID>] <PACKAGE>
    返回给定应用的有害应用警告消息(如果存在)

  uninstall-system-updates [<PACKAGE>]
    删除给定系统应用程序的更新并回退到其 /system 版本。如果给定的包不是系统应用程序,则不执行任何操作。
    如果未指定包,则删除所有系统应用程序的更新。

  get-moduleinfo [--all | --installed] [module-name]
    显示模块信息。 如果仅指定了模块名称,则显示该信息默认情况下,不带任何参数仅显示已安装的模块。
       --all:显示所有模块信息
       --installed:仅显示已安装的模块

  log-visibility [--enable|--disable] <PACKAGE>
    当给定包的可见性被阻止时打开调试日志记录。
       --enable:打开调试日志(默认)
       --disable: 关闭调试日志

  set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>] [--throttle-time <SECONDS>] [--reset]
    设置静默更新的策略。
      --allow-unlimited-silent-updates:允许来自安装程序的无限制的静默更新安装请求,无需限制时间。
      --throttle-time:以秒为单位更新静默更新限制时间。
      --reset:将安装程序和节流时间恢复为默认值,并清除系统中的静默更新轨迹。

  get-app-links [--user <USER_ID>] [<PACKAGE>]
    打印给定包的域验证状态,如果未指定,则打印所有包的域验证状态。状态码定义如下:
        - none:该域没有任何记录
        - verified:该域已成功验证
        - approved:强制批准,通常通过 shell
        - denied:强制拒绝,通常通过 shell
        - migrated:保留来自旧响应的验证
        - restored:从用户数据恢复中保留验证
        - legacy_failure:被遗留验证者拒绝,原因不明
        - system_configured:由设备配置自动批准
        - >= 1024:特定于设备验证程序的自定义错误代码
      --user <USER_ID>: 包括用户选择(包括所有域,而不仅仅是自动验证域)
  reset-app-links [--user <USER_ID>] [<PACKAGE>]
    重置给定包的域验证状态,如果未指定,则为所有包重置域验证状态。
      --user <USER_ID>: 改为清除用户选择状态;请注意,这意味着不会清除域验证状态
      <PACKAGE>: 要重置的包,或“all”重置所有包
  verify-app-links [--re-verify] [<PACKAGE>]
    广播给定包的验证请求,如果没有指定,则广播所有包的验证请求。仅在包先前未记录响应时才发送。
      --re-verify: 即使包记录了响应也发送
  set-app-links [--package <PACKAGE>] <STATE> <DOMAINS>...
    手动设置包的域状态。域必须由包声明为 autoVerify 才能正常工作。对于无法应用的域,此命令不会报告失败。
      --package <PACKAGE>: 要设置的包,或者“all”设置所有包
      <STATE>: 设置域的代码,有效值为:
        STATE_NO_RESPONSE (0): 重置,就好像没有记录任何响应一样。
        STATE_SUCCESS (1):将域视为已通过域成功验证。 验证代理。 请注意,域验证代理可以覆盖它。
        STATE_APPROVED (2):将域视为始终已批准,防止域验证代理对其进行更改。
        STATE_DENIED (3):将域视为始终被拒绝,防止域验证代理更改它。
       <DOMAINS>:以空格分隔的要更改的域列表,或“全部”以更改每个域。
  set-app-links-user-selection --user <USER_ID> [--package <PACKAGE>] <ENABLED> <DOMAINS>...
    手动设置包的主机用户选择状态。域必须由包声明才能正常工作。对于无法应用的域,此命令不会报告失败。
      --user <USER_ID>:要更改选择的用户
      --package <PACKAGE>:要设置的包
      <ENABLED>:是否批准域
      <DOMAINS>:以空格分隔的要更改的域列表,或“全部”以更改每个域。
  set-app-links-allowed --user <USER_ID> [--package <PACKAGE>] <ALLOWED> <ENABLED> <DOMAINS>...
    切换包的自动验证链接处理设置。
      --user <USER_ID>:要更改选择的用户
      --package <PACKAGE>:要设置的包,或者“all”设置所有包,如果没有指定一个包,包将被重置。
      <ALLOWED>:true 允许包打开自动验证链接,false 禁用
  get-app-link-owners [--user <USER_ID>] [--package <PACKAGE>] [<DOMAINS>]
    按优先级从低到高的顺序打印给定用户的特定域的所有者。
      --user <USER_ID>:要查询的用户
      --package <PACKAGE>:还可以选择为包声明的所有 Web 域打印,或“all”以打印所有包
      --<DOMAINS>:要查询的以空格分隔的域列表

am

android自带的命令也有些linux本身没有,而android特有的。例如android的am命令,在手机连接adb后,可通过am命令做很多操作:

  1. 拨打电话10086
adb shell am start -a android.intent.action.CALL -d tel:10086
  1. 打开网站http://www.baidu.com
adb shell am start -a android.intent.action.VIEW -d http://www.baidu.com
  1. 启动Activity:启动包名为com.yuanhh.app,主Activity为.MainActivity,且extra数据以”website”为key, “yuanh.com”为value。通过java代码要完成该功能虽然不复杂,但至少需要一个android环境,而通过adb的方式,只需要在adb窗口,输入如下命令便可完成
am start -n com.yuanhh.app/.MainActivity -es website gityuan.com

am命令还可以启动Service、Broadcast,杀进程,监控等功能,这些功能都非常便捷调试程序,接下来讲述关于am更多更详细的功能。

Am命令

命令格式:adb shell am [subcommand] [options] 即命令后面跟着一个子命令,因为是子命令而不是参数,所以不用加-,而后面的参数就需要加-,比如am start -a *,start在这里就是子命令,-a在这里就是参数。直接去看下am的代码Am.java。每次在shell环境下执行am即启动一个线程执行Am.java的主函数,这个主函数的主要实现都在run方法里面,am命令后面带的参数会当做运行时参数传递个主方法,后面会根据传入的参数不同,执行不同的条件分支。可以看到当参数的个数小于1的时候,就执行showUsage()方法,即说明am命令使用方式的方法,并且有最常用的参数intent的详细使用说明。am命令中最常用到的是start命令,下面来看下这个命令的执行过程。

代码根据第一个参数判断是否是start子命令,进入private void runStart() throws Exception方法,接着进入执行解析参数的关键方法 private Intent makeIntent(int defUser) throws URISyntaxException里面。makeIntent里面用while循环根据传入的参数一点一点的配置即将使用的intent,大的比如intent的action,data小的比如flag,参数等。回到runStart方法,首先是检查am start是否接着-S(stop)参数,如果不是就跨进程调用am服务执行命令。到这里am及其start子命令的执行过程基本介绍完了。

目标文件在\frameworks\base\cmds\am\src\com\android\commands\am
命令窗口通过adb shell 进入android 的Linux命令界面,输入am -help看到信息:

命令列表:

命令功能实现方法
am start [options] 启动Activityam start -n com.android.myapplication/.MainActivitystartActivityAsUser
am startservice 启动ServicestartService
am stopservice 停止ServicestopService
am broadcast 发送广播broadcastIntent
am kill 杀指定后台进程killBackgroundProcesses
am kill-all杀所有后台进程killAllBackgroundProcesses
am force-stop 强杀进程forceStopPackage
am hang系统卡住hang
am restart重启restart
am bug-report创建bugreportrequestBugReport
am dumpheap 进程pid的堆信息输出到filedumpheap
am send-trim-memory 收紧进程的内存setProcessMemoryTrimLevel
am monitor监控MyActivityController.run

注:在SDK17之后,由于权限的问题,要记得在加上 –USER 0(视手机而定)
例如:AM BROADCAST –USER 0 -A COM.EXAMPLE.TEST

am命令实的实现方式在Am.java,最终几乎都是调用ActivityManagerService相应的方法来完成的,am monitor除外。比如前面介绍的命令am start -a android.intent.action.VIEW -d http://www.baidu.com, 启动Acitivty最终调用的是ActivityManagerService类的startActivityAsUser()方法来完成的。再比如am kill-all命令,最终的实现工作是由ActivityManagerService的killBackgroundProcesses()方法完成的。

接下来,说说[options]和 参数的意义以及如何正确取值。

Options

启动Activity

主要是启动Activity命令am start [options] 使用options参数,接下来列举Activity命令的[options]参数:

参数意义
-D允许调试功能
-W等待app启动完成
-R 重复启动Activity COUNT次
-S启动activity之前,先调用forceStopPackage()方法强制停止app
-opengl -trace运行获取OpenGL函数的trace
-user <USER_ID>current: 指定用户来运行App,默认为当前用户
-start -profiler 启动profiler,并将结果发送到
-P 类似 -start -profiler,不同的是当app进入idle状态,则停止profiling
-sampling INTERVAL设置profiler 取样时间间隔,单位ms
启动Activity的实现原理: 存在-W参数则调用startActivityAndWait()方法来运行,否则startActivityAsUser()。

收紧内存
命令

am send-trim-memory  <pid> <level>

例如: 向pid=12345的进程,发出level=RUNNING_LOW的收紧内存命令

am send-trim-memory 12345 RUNNING_LOW。

那么level取值范围为: HIDDEN、RUNNING_MODERATE、BACKGROUND、RUNNING_LOW、MODERATE、RUNNING_CRITICAL、COMPLETE。

其他
对于am的子命令,startservice, stopservice, broadcast, kill, profile start, profile stop, dumpheap的可选参数都允许设置--user <USER_ID>。目前市面上的绝大多数手机还是单用户模式,故可以忽略该参数,默认为当前用户。

例如:启动id=10010的用户的指定service。

am startservice --user 10010

Intent

Intent的参数和flags较多,本文为方便起见,分为3种类型参数,常用参数,Extra参数,Flags参数。

常用参数

  • -a <ACTION>: 指定Intent action, 实现原理Intent.setAction();
  • -n <COMPONENT>: 指定组件名,格式为{包名}/.{主Activity名},实现原理Intent.setComponent();
  • -d <DATA_URI>: 指定Intent data URI
  • -t <MIME_TYPE>: 指定Intent MIME Type
  • -c <CATEGORY> [-c <CATEGORY>] ...]:指定Intent category,实现原理Intent.addCategory()
  • -p <PACKAGE>: 指定包名,实现原理Intent.setPackage();
  • -f <FLAGS>: 添加flags,实现原理Intent.setFlags(int ),紧接着的参数必须是int型;

实例

am start -a android.intent.action.VIEW / -a com.google.android.gms.phenotype.UPDATE
am start -n com.yuanhh.app/.MainActivity / -n com.google.android.contacts/com.google.android.libraries.phenotype.client.stable.PhenotypeUpdateBackgroundBroadcastReceiver
am start -d content://contacts/people/1
am start -t image/png
am start -c android.intent.category.APP_CONTACTS
am start -p "packagename"

//发广播实例
adb shell am broadcast -a com.google.android.gms.phenotype.UPDATE -n com.google.android.contacts/com.google.android.libraries.phenotype.client.stable.PhenotypeUpdateBackgroundBroadcastReceiver -p "com.google.android.contacts"
Broadcasting: Intent { act=com.google.android.gms.phenotype.UPDATE flg=0x400000 pkg=com.google.android.contacts cmp=com.google.android.contacts/com.google.android.libraries.phenotype.client.stable.PhenotypeUpdateBackgroundBroadcastReceiver }
Broadcast completed: result=0

Extra参数
(1). 基本类型
| 参数 |-e/-es | -esn | -ez | -ei | -el | -ef | -eu | -ecn |
|–|–|–|–|–|–|–|–|–|–|
| 类型 | String | (String)null | boolean | int | long | float | uri | component |

比如参数es是Extra String首字母简称,实例:

am start -n com.yuanhh.app/.MainActivity -es website gityuan.com

此处-es website gityuan.com,等价于Intent.putExtra(“website”, “gityuan.com”);

(2). 数组类型

参数-esa-eia-ela-efa
数组类型String[]int[]long[]float[]

比如参数eia,是Extra int array首字母简称,多个value值之间以逗号隔开,实例:

am start -n com.yuanhh.app/.MainActivity -ela weekday 1,2,3,4,5

此处-ela weekday 1,2,3,4,5,等价于Intent.putExtra(“weekday”, new int[]{1,2,3,4,5});

(3). ArrayList类型

参数-esal-eial-elal-efal
List类型Stringintlongfloat

比如参数efal,是Extra float Array List首字母简称,多个value值之间以逗号隔开,实例:

am start -n com.yuanhh.app/.MainActivity -efal nums 1.2,2.2

此处-efal nums 1.2,2.2,等价于先构造ArrayList变量,再通过putExtra放入第二个参数。

Flags参数
在前面Intent参数中提到有-f ,是通过Intent.setFlags(int )方法,来设置Intent的flags.本小节也是关于flags,是通过Intent.addFlags(int )方法。如下所示,所有的flags参数。

[--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]

例如,发送action=”broadcast.demo”的广播,并且对于forceStopPackage()的应用不允许接收该广播,命令如下:

am broadcast -a broadcast.demo --exclude-stopped-packages

所有

15:59:42[~]~$  adb shell am help
Activity manager (activity) commands:
  help
      Print this help text.
  start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>] [--sampling INTERVAL] [--streaming] [-R COUNT] [-S] [--track-allocation] [--user <USER_ID> | current] <INTENT>
      开始一个活动。选项是:
      -D:启用调试
      -N:启用本机调试
      -W:等待启动完成
      --start-profiler <FILE>:启动分析器并将结果发送到 <FILE>
      --sampling INTERVAL:使用样本分析,样本之间有 INTERVAL 微秒(与 --start-profiler 一起使用)
      --streaming:将分析输出流式传输到指定文件(与 --start-profiler 一起使用)
      -P <FILE>:和上面一样,但是当应用程序空闲时分析停止
      --attach-agent <agent>: 在绑定之前附加给定的代理
      --attach-agent-bind <agent>: 在绑定期间附加给定的代理
      -R:重复活动启动 <COUNT> 次。在每次重复之前,将完成最上面的活动。
      -S:在启动活动之前强制停止目标应用程序
      --track-allocation:启用对象分配跟踪
      --user <USER_ID> | current:指定以哪个用户身份运行;如果未指定,则以当前用户身份运行。
      --windowingMode <WINDOWING_MODE>:启动活动的窗口模式。
      --activityType <ACTIVITY_TYPE>:启动活动的活动类型。
      --display <DISPLAY_ID>:启动活动的显示器。
      
  start-service [--user <USER_ID> | current] <INTENT>
      启动服务。选项是:
      --user <USER_ID> | current: 指定以哪个用户身份运行;如果未指定,则以当前用户身份运行。
      
  start-foreground-service [--user <USER_ID> | current] <INTENT>
      Start a foreground Service.  Options are:
      --user <USER_ID> | current: 指定以哪个用户身份运行;如果未指定,则以当前用户身份运行。

  stop-service [--user <USER_ID> | current] <INTENT>
      Stop a Service.  Options are:
      --user <USER_ID> | current: 指定以哪个用户身份运行;如果未指定,则以当前用户身份运行。
      
  broadcast [--user <USER_ID> | all | current] [--receiver-permission <PERMISSION>] [--allow-background-activity-starts]
          [--async] <INTENT>
      Send a broadcast Intent.  Options are:
      --user <USER_ID> | all | current: 指定发送给哪个用户;如果未指定,则发送给所有用户。
      --receiver-permission <PERMISSION>: 要求接收者持有许可。
      --allow-background-activity-starts: 即使在后台,接收者也可以启动活动。
      --async: 发送而不等待接收者完成。

  instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]
          [--user <USER_ID> | current]
          [--no-hidden-api-checks [--no-test-api-access]]
          [--no-isolated-storage]
          [--no-window-animation] [--abi <ABI>] <COMPONENT>
      启动仪器。通常,此目标 <COMPONENT> 采用 <TEST_PACKAGE>/<RUNNER_CLASS> 的形式,如果只有一个检测,则只有 <TEST_PACKAGE>。选项是:
      -r:打印原始结果(否则解码 REPORT_KEY_STREAMRESULT)。与 [-e perf true] 一起使用以生成用于性能测量的原始输出。
      -e <NAME> <VALUE>:将参数 <NAME> 设置为 <VALUE>。对于测试运行器,常见的形式是 [-e <testrunner_flag> <value>[,<value>...]]-p <FILE>:将分析数据写入 <FILE>
      -m:将输出作为 protobuf 写入标准输出(机器可读)
      -f <Optional PATH/TO/FILE>:将输出作为 protobuf 写入文件(机器可读)。如果未指定路径,将使用默认目录和文件名:/sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto
      -w:等待检测完成后再返回。测试运行者需要。
      --user <USER_ID> |current:指定用户仪表运行;当前用户(如果未指定)。
      --no-hidden-api-checks:禁用对隐藏 API 使用的限制。
      --no-test-api-access:如果启用了隐藏 API 检查,则不允许访问测试 API。
      --no-isolated-storage:不使用隔离存储沙箱并挂载完整的外部存储
      --no-window-animation:运行时关闭窗口动画。
      --abi <ABI>:使用选定的 ABI 启动检测进程。这假定进程支持选定的 ABI。

  trace-ipc [start|stop] [--dump-file <FILE>]
      跟踪 IPC 交易。
      start: 开始跟踪 IPC 事务。
      stop: 停止跟踪 IPC 事务并将结果转储到文件中。
      --dump-file <FILE>: 指定跟踪应转储到的文件。

  profile start [--user <USER_ID> current] [--sampling INTERVAL | --streaming] <PROCESS> <FILE>
      在进程上启动探查器。给定的 <PROCESS> 参数可以是进程名称或 pid。选项是:
      --user <USER_ID> | current:提供进程名称时,指定要配置的进程用户;如果未指定,则使用当前用户。
      --sampling INTERVAL:使用样本分析,样本之间有 INTERVAL 微秒。
      --streaming:将分析输出流式传输到指定文件。
  profile stop [--user <USER_ID> current] <PROCESS>
      在进程上停止探查器。给定的 <PROCESS> 参数可以是进程名称或 pid。选项是:
      --user <USER_ID> | current:提供进程名称时,指定要配置的进程用户;如果未指定,则使用当前用户。
      
  dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>
      转储进程的堆。给定的 <PROCESS> 参数可以是进程名称或 pid。选项是:
      -n:转储本机堆而不是托管堆
      -g:在转储堆之前强制 GC
      --user <USER_ID> | current:提供进程名称时,指定要转储的进程的用户;如果未指定,则使用当前用户。

  set-debug-app [-w] [--persistent] <PACKAGE>
      将应用程序 <PACKAGE> 设置为调试。选项是:
      -w:应用程序启动时等待调试器
      --persistent:保留这个值
  clear-debug-app
      清除之前设置的调试应用程序

  set-watch-heap <PROCESS> <MEM-LIMIT>
      开始监视 <PROCESS> 的 pss 大小,如果它等于或高于 <HEAP-LIMIT>,则收集堆转储供用户报告。
  clear-watch-heap
      清除之前设置的观察堆。

  clear-exit-info [--user <USER_ID> | all | current] [package]
      清除给定包的进程退出信息

  bug-report [--progress | --telephony]
      请求生成错误报告;完成后将启动通知以选择应交付的位置。选项是:
     --progress:将立即启动通知以显示其进度。
     --telephony:将只转储电话部分。

  fgs-notification-rate-limit {enable | disable}
     启用/禁用 FGS 通知延迟策略的速率限制。

  force-stop [--user <USER_ID> | all | current] <PACKAGE>
      完全停止给定的应用程序包。
  crash [--user <USER_ID>] <PACKAGE|PID>
      在指定的包或进程中引发 VM 崩溃
  kill [--user <USER_ID> | all | current] <PACKAGE>
      杀死与给定应用程序关联的所有后台进程。
  kill-all
      杀死所有可以安全杀死的进程(缓存等)。

  make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>
      如果给定应用程序的 uid 在后台并等待空闲(不允许后台服务),请立即执行此操作。
  monitor [--gdb <port>]
      开始监控崩溃或 ANR。
      --gdb: 在崩溃/ANR 时在给定端口上启动 gdbserv
  watch-uids [--oom <uid>]
      开始观察和报告 uid 状态变化。
      --oom:指定要报告详细更改消息的 uid。

  hang [--allow-restart]
      挂起系统。
      --allow-restart:允许watchdog执行正常的系统重启
  restart
      重新启动用户空间系统。
  idle-maintenance
      现在进行空闲维护。
  screen-compat [on|off] <PACKAGE>
      <PACKAGE> 的控制屏幕兼容模式。
  package-importance <PACKAGE>
      打印 <PACKAGE> 的当前重要性。

  to-uri [INTENT]
     将给定的 Intent 规范打印为 URI。
  to-intent-uri [INTENT]
      将给定的 Intent 规范打印为意图:URI。
  to-app-uri [INTENT]
      将给定的 Intent 规范打印为 android-app: URI。

  switch-user <USER_ID>
      切换到将 USER_ID 置于前台,如果该用户当前已停止,则开始执行该用户。
  get-current-user
      返回当前前台用户的 id。
  start-user [-w] <USER_ID>
      如果当前已停止,则在后台启动 USER_ID;如果要在前台启动用户,请使用 switch-user。
      -w:等待启动用户完成并解锁用户。
  unlock-user <USER_ID> [TOKEN_HEX]
      尝试使用给定的授权令牌解锁给定的用户。
  stop-user [-w] [-f] <USER_ID>
      停止执行 USER_ID,不允许它运行任何代码,直到稍后显式启动或切换到它。
      -w:等待停止用户完成。
      -f:即使有相关用户无法停止也强制停止。
  is-user-stopped <USER_ID>
      返回 <USER_ID> 是否已停止。
  get-started-user-state <USER_ID>
      获取给定启动用户的当前状态。

  track-associations
      启用关联跟踪。
  untrack-associations
      禁用和清除关联跟踪。

  get-uid-state <UID>
      获取给定 <UID> 的应用程序的进程状态。

  attach-agent <PROCESS> <FILE>
    将代理附加到指定的 <PROCESS>,它可以是进程名称或 PID。

  get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]
      检索设备的配置和任何最近的配置。
      --days: 还返回最近 N 天已经看到的配置。
      --device:还输出全局设备配置信息。
      --proto:将结果作为原型返回;不包括 --days 信息。
      --display:指定运行命令的显示器;如果未指定,则运行默认显示。

  supports-multiwindow
      如果设备支持多窗口,则返回 true。
  supports-split-screen-multi-window
      如果设备支持分屏多窗口,则返回 true。
  suppress-resize-config-changes <true|false>
      由于用户调整 活动/任务 的大小而抑制配置更改。

  set-inactive [--user <USER_ID>] <PACKAGE> true|false
      设置应用的非活动状态
  get-inactive [--user <USER_ID>] <PACKAGE>
      返回应用程序的非活动状态。

  set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare|restricted
      将应用程序放入备用存储桶。
  get-standby-bucket [--user <USER_ID>] <PACKAGE>
      返回应用的备用存储桶。

  send-trim-memory [--user <USER_ID>] <PROCESS> [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]
      将内存调整事件发送到 <PROCESS>。也可以提供原始修整 int 级别。

  display [COMMAND] [...]: 用于在显示器上操作的子命令。
       move-stack <STACK_ID> <DISPLAY_ID><STACK_ID> 从其当前显示移动到 <DISPLAY_ID>。

  stack [COMMAND] [...]: 用于操作活动堆栈的子命令。
       move-task <TASK_ID> <STACK_ID> [true|false]<TASK_ID> 从其当前堆栈移动到 <STACK_ID> 的顶部 (true) 或底部 (false)。
       list
           列出所有活动堆栈及其大小。
       info <WINDOWING_MODE> <ACTIVITY_TYPE><WINDOWING_MODE><ACTIVITY_TYPE> 中显示有关活动堆栈的信息。
       remove <STACK_ID>
           删除堆栈 <STACK_ID>.

  task [COMMAND] [...]: 用于操作活动任务的子命令。
       lock <TASK_ID><TASK_ID> 放在最前面,不允许其他任务运行。
       lock stop
           结束当前任务锁定。
       resizeable <TASK_ID> [0|1|2|3]<TASK_ID> 的可调整大小模式更改为以下之一: 0:不可调整大小 1:crop_windows 2:可调整大小  3:resizeable_and_pipable
       resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>
           确保 <TASK_ID> 在具有指定边界的堆栈中。
           如果没有现有堆栈具有指定的边界,则强制任务可调整大小并创建堆栈。
  update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]<USER_ID> 更新列出的包的 ApplicationInfo 对象,而无需重新启动任何进程。

  write
      将所有挂起状态写入存储。
  compat [COMMAND] [...]: 用于切换 app-compat 更改的子命令。
         enable|disable [--no-kill] <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>
            通过 <PACKAGE_NAME> 的 ID 或名称切换更改。
            它会杀死 <PACKAGE_NAME> (以允许切换生效),除非提供了 --no-kill 。
         reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>
            通过 <PACKAGE_NAME> 的 ID 或名称切换更改。
            它会杀死 <PACKAGE_NAME>(以使切换生效)。
         enable-all|disable-all <targetSdkVersion> <PACKAGE_NAME>
            切换由 <targetSdkVersion> 控制的所有更改。
         reset-all [--no-kill] <PACKAGE_NAME>
            删除所有更改的所有现有覆盖
            <PACKAGE_NAME> (返回默认行为).
            它会杀死 <PACKAGE_NAME> (以允许切换生效),除非提供了 --no-kill 。

  memory-factor [command] [...]: 于覆盖内存压力因子的子命令
         set <NORMAL|MODERATE|LOW|CRITICAL>
            覆盖内存压力因子。也可以提供原始 int 级别
         show
            显示现有的内存压力因子
         reset
            删除现有的内存压力因子覆盖

  service-restart-backoff <COMMAND> [...]: 用于切换服务重启退避策略的子命令。
         enable|disable <PACKAGE_NAME>
            打开/关闭 <PACKAGE_NAME> 的重启退避策略。
         show <PACKAGE_NAME>
            显示 <PACKAGE_NAME> 的重新启动退避策略状态。

  get-isolated-pids <UID>
         使用此 <UID> 中的包获取隔离进程的 PID

dumpsys

查看系统服务

路径

frameworks/native/cmds/dumpsys
frameworks/native/cmds/dumpsys/dumpsys.cpp
frameworks/native/cmds/dumpsys/dumpsys.h

命令

adb shell dumpsys

输出信息的开始部分就是所有运行的service

14:41:21[~]~$  adb shell dumpsys
Currently running services:
  DockObserver
  SurfaceFlinger
  accessibility
  account
  activity
  activity_task
  adb
  alarm
  android.frameworks.stats.IStats/default
  android.hardware.gnss.IGnss/default
  android.hardware.identity.IIdentityCredentialStore/default
  android.hardware.light.ILights/default
  android.hardware.neuralnetworks.IDevice/qti-default
  android.hardware.neuralnetworks.IDevice/qti-dsp
  android.hardware.neuralnetworks.IDevice/qti-gpu
  android.hardware.power.IPower/default
  android.hardware.security.keymint.IKeyMintDevice/default
  android.hardware.security.keymint.IRemotelyProvisionedComponent/default
  android.hardware.security.secureclock.ISecureClock/default
  android.hardware.security.sharedsecret.ISharedSecret/default
  android.hardware.vibrator.IVibrator/default
  ......

adb shell dumpsys --hlep

14:43:17[~]~$  adb shell dumpsys --hlep
dumpsys: unrecognized option `--hlep'

usage: dumpsys
         To dump all services.
or:
       dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--thread] [--help | -l | --skip SERVICES | SERVICE [ARGS]]
         --help: shows this help
         -l: only list services, do not dump them
         -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds
         -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds
         --pid: dump PID instead of usual dump
         --thread: dump thread usage instead of usual dump
         --proto: filter services that support dumping data in proto format. Dumps
               will be in proto format.
         --priority LEVEL: filter services based on specified priority
               LEVEL must be one of CRITICAL | HIGH | NORMAL
         --skip SERVICES: dumps all services but SERVICES (comma-separated list)
         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it

adb shell dumpsys -l

查看系统服务信息 等同于 adb shell service list

查询到运行的system service后,就可以在dumpsys后面加上service的名字,查看指定的service信息。

adb shell dumpsys activity
adb shell dumpsys cpuinfo
adb shell dumpsys battery
adb shell dumpsys window(最后部分可以看到分辨率的信息)

举例
adb shell service list | grep activity  显示的信息比较多
adb shell dumpsys -l | grep activity
进入adb shell后,可以使用grep
但没有进入adb shell环境,可以用findstr代替grep

有些service能够接收额外的参数,我们可以使用-h查看帮助信息。
adb shell dumpsys servicename -h

获取设备最上层即跟用户交互层的activity
adb shell dumpsys activity activities

adb shell dumpsys activity activities查看Activity组件信息
adb shell dumpsys activity services查看Service组件信息
adb shell dumpsys activity providers产看ContentProvider组件信息
adb shell dumpsys activity broadcasts查看BraodcastReceiver信息
adb shell dumpsys activity intents查看Intent信息
adb shell dumpsys activity processes查看进程信息
adb shell am stack list查看栈列表,记录
adb shell dumpsys package 包名查看该包的具体信息,例如:

Activity Resolver Table:
  Non-Data Actions:
      android.intent.action.MAIN:
        9eee46a com.****
          Action: "android.intent.action.MAIN"
          Category: "android.intent.category.LAUNCHER"

Receiver Resolver Table:
  Non-Data Actions:
      android.media.AUDIO_BECOMING_NOISY:
        90edd36 com.***Receiver filter ***
          Action: "android.intent.action.MEDIA_BUTTON"
          Action: "android.media.AUDIO_BECOMING_NOISY"
      android.intent.action.MEDIA_BUTTON:
        90edd36 com.***Receiver filter ***
          Action: "android.intent.action.MEDIA_BUTTON"
          Action: "android.media.AUDIO_BECOMING_NOISY"

Service Resolver Table:
  Non-Data Actions:
      android.media.AUDIO_BECOMING_NOISY:
        4334da4 com.***Service filter ***
          Action: "android.intent.action.MEDIA_BUTTON"
          Action: "android.media.AUDIO_BECOMING_NOISY"
          Action: "android.media.browse.MediaBrowserService"
      android.media.browse.MediaBrowserService:
        4334da4 com.***Service filter ***
          Action: "android.intent.action.MEDIA_BUTTON"
          Action: "android.media.AUDIO_BECOMING_NOISY"
          Action: "android.media.browse.MediaBrowserService"
      android.intent.action.MEDIA_BUTTON:
        4334da4 com.***Service filter ***
          Action: "android.intent.action.MEDIA_BUTTON"
          Action: "android.media.AUDIO_BECOMING_NOISY"
          Action: "android.media.browse.MediaBrowserService"

Domain verification status:

Key Set Manager:
  [com.***]
      Signing KeySets: 1

Packages:
  Package [com.***] (***):
    userId=***
    pkg=Package{*** com.***}
    codePath=/system_ext/app/***
    resourcePath=/system_ext/app/***
    legacyNativeLibraryDir=/system_ext/app/***/lib
    extractNativeLibs=false
    primaryCpuAbi=null
    secondaryCpuAbi=null
    cpuAbiOverride=null
    versionCode=6 minSdk=31 targetSdk=31
    minExtensionVersions=[]
    versionName=6.0
    usesNonSdkApi=true
    splits=[base]
    apkSigningVersion=3
    applicationInfo=PackageImpl{*** com.***}
    flags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ]
    privateFlags=[ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE ALLOW_AUDIO_PLAYBACK_CAPTURE SYSTEM_EXT PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]
    forceQueryable=false
    queriesPackages=[]
    queriesIntents=[Intent { act=android.***Service }, Intent { act=android.***Service }]
    dataDir=/data/user/0/com.***
    supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
    timeStamp=2022-03-11 15:47:29
    firstInstallTime=2022-02-09 20:27:05
    lastUpdateTime=2022-03-11 15:47:29
    signatures=PackageSignatures{*** version:3, signatures:[***], past signatures:[]}
    installPermissionsFixed=true
    pkgFlags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ]
    declared permissions:
      android.permission.***: prot=normal, INSTALLED
    requested permissions:
      android.permission.***
			...
    install permissions:
      android.permission.***: granted=true
			...
    User 0: ceDataInode=6254 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
      gids=[3002, 3003]
      runtime permissions:
        android.permission.***: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]

Queries:
  system apps queryable: false
  forceQueryable:
    com.***
  queries via package name:
  queries via intent:
    com.***:
      com.***
      com.***
      com.***
  queryable via interaction:
    User 0:
      [com.***]:
        com.***
      com.***:
        com.***
      com.***:
        [com.***]
      com.***:
        com.***
  queryable via uses-library:

Package Changes:
  Sequence number=6
  User 0:
    seq=1, package=com.***
    seq=5, package=com.***


Dexopt state:
  [com.***]
    path: /system_ext/app/***/***.apk
      arm64: [status=extract] [reason=post-boot]


Compiler stats:
  [com.***]
     ***.apk - 210

APEX session state:

Active APEX packages:


Inactive APEX packages:


Factory APEX packages:


Snapshot statistics
   Unrecorded-hits: 1538  Cork-level: 0
   Summary stats               TotBlds     TotUsed     TotCork     BigBlds    ShortLvd     TotTime     MaxTime

   Build times                  <= 1ms      <= 2ms      <= 5ms     <= 10ms     <= 20ms     <= 50ms    <= 100ms     > 100ms


   Use counters                   <= 1        <= 2        <= 5       <= 10       <= 20       <= 50      <= 100       > 100

cmd

overlay

adb shell cmd overlay lookup --verbose android android:TYPE/NAME 查看系统framework字符资源值

adb shell cmd overlay lookup --verbose package package:TYPE/NAME 查看包的字符资源值
例如:adb shell cmd overlay lookup --verbose xxx xxx:string/xxx

17:36:56[~]~$  adb shell cmd overlay help
Overlay manager (overlay) commands:
  help
    Print this help text.
  dump [--verbose] [--user USER_ID] [[FIELD] PACKAGE[:NAME]]
    打印有关覆盖管理器的调试信息。
    使用可选参数 PACKAGE 和 NAME,将输出限制为指定的覆盖或目标。使用可选参数 FIELD,将输出限制为相应的 SettingsItem 字段。字段名称全部小写并省略 m 前缀,即 SettingsItem.mUserId 的 'userid'。
  list [--user USER_ID] [PACKAGE[:NAME]]
    打印有关目标和覆盖包的信息。
    覆盖包装按优先顺序打印。使用可选参数 PACKAGE 和 NAME,将输出限制为指定的覆盖或目标。
  enable [--user USER_ID] PACKAGE[:NAME]
    使用可选的唯一名称启用包内或由包拥有的覆盖。
  disable [--user USER_ID] PACKAGE[:NAME]
    使用可选的唯一名称禁用覆盖或由 PACKAGE 拥有。
  enable-exclusive [--user USER_ID] [--category] PACKAGE
    在 PACKAGE 内启用覆盖或由 PACKAGE 拥有,并为其目标包禁用所有其他覆盖。如果给出 --category 选项,则仅禁用同一类别中的其他覆盖。
  set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest
    将覆盖的优先级更改为刚好高于 PARENT 的优先级 如果 PARENT 是特殊关键字“lowest”,则将 PACKAGE 的优先级更改为最低优先级。 如果 PARENT 是特殊关键字“最高”,则将 PACKAGE 的优先级更改为最高优先级。
  lookup [--user USER_ID] [--verbose] PACKAGE-TO-LOAD PACKAGE:TYPE/NAME
    加载一个包并打印应用当前配置和启用覆盖的给定资源的值。
     要获得更细粒度的替代方案,请使用 'idmap2 lookup'。
  fabricate [--user USER_ID] [--target-name OVERLAYABLE] --target PACKAGE
            --name NAME PACKAGE:TYPE/NAME ENCODED-TYPE-ID ENCODED-VALUE
    从单个资源创建覆盖。 调用者必须是 root。 例子:
      fabricate --target android --name LighterGray \
                android:color/lighter_gray 0x1c 0xffeeeeee

apktool apk工具

用法:apktool
  -advance,--advanced 打印高级信息。
  -version,--version 打印版本然后退出
用法: apktool if|install-framework [options] <framework.apk>
  -p,--frame-path <dir> 将框架文件存储到 <dir> 中。
  -t,--tag <tag> 使用 <tag> 标记框架。
用法: apktool d[ecode] [options] <file_apk>
  -f,--force 强制删除目标目录。
  -o,--output <dir> 写入的文件夹的名称。 默认为 apk.out
  -p,--frame-path <dir> 使用位于 <dir> 中的框架文件。
  -r,--no-res 不解码resources.
  -s,--no-src 不解码sources.
  -t,--frame-tag <tag> 使用由 <tag> 标记的框架文件。
用法: apktool b[uild] [options] <app_path>
  -f,--force-all 跳过更改检测并构建所有文件。
  -o,--output <dir> 写入的 apk 的名称。 默认为 dist/name.apk
  -p,--frame-path <dir> 使用位于 <dir> 中的框架文件。
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值