Android调试桥-Android Debug Birdge详解
原文:http://android.eoe.cn/topic/summary
Android调试桥-Android Debug Birdge
Android调试桥(adb)是一个多功能的命令行功具,它可以让你与一个模拟器实例通信或是连接到android设备上。它是一个客户端-服务器程序,包括三个部份:
- 客户端,在你开发的机器上运行。你可以在一个shell中通过调用adb命令来启动一个客户端程序。其它工具,如ADT插件和DDMS也可以创建adb客户端程序.
- 服务器,它是运行在你开发机器上的一个后台程序,负责客户端程序与运行在模拟器或android设备上的adb进程间的通信.
- 后台进程,它运行在每一个模拟器或android设备上。
你可以在/platform-tools/路径下找到adb工具。
当你启动一个adb客户端时,这个客户端首先检查adb服务器是否已经启动.如果没有,它将启动一个服务器.当服务器启动后,它将绑定到本地的TCP5037端口并监听来自adb客户端的指令--所有adb客户端使用5037号端口与adb服务器通信.
在这之后,服务器将为所有正在运行的模拟器/android设备建立连接.它通过扫描从5555到5585号端口之间的所有基数号端口来定位模拟器/设备实例.当它发现一个adb后台进程时,它就用这个端口建立一个连接.注意,每一个模拟器/android设备实例占用了一对连续的端口-一个偶数号端口用作控件台连接和一个基数号端口用作与adb建立连接。例如:
- 模拟器 1, 控制台:5554
- 模拟器 1, adb:5555
- 模拟器 2, 控制台:5556
- 模拟器 2, adb:5557
如上所述,使用5555号端口与adb连接的模拟器实例和使用5554号端口与控制台连接的实例为同一个实例。
当服务器与所用的模拟器实例建立了连接之后,你可以使用adb命令来接入这些实例。因为服务器管理着与模拟器/手机的连接,并处理来自多个adb客户端的命令,你可以通过任意一个adb客户端(或从一个脚本)来控制任何你想要控制的模拟器/手机设备。
注意: 当你将一个使用Android 4.4.4或更高版本的设备连接到电脑时, 系统将弹出一个对话框,询问你是否接受一个RSA密钥,这个密钥将允许通过电脑对设备进行调试。这种安全机制将更好的保护用户的设备,因为它确保了USB调试或是其它adm命令不被执行,除非你将设备解锁,并确认了这个对话框。这要求你的adb版本达到1.0.31(在SDK平台工具版本r16.0.1及以后版本中可用),这样才能对使用Android 4.2.2或更高版本的设备进行调试。
语法-Syntax
你可以在你的开发机器或是一个脚本工具中通过命令行调用adb密令。它的使用语法是:
1 |
adb [-d|-e|-s <serialNumber>]<command>
|
如果当前只有一个模拟器在运行或只有一个设备被连接,adb命令默认的被发送到这个设备上。如果有多个模拟器在运行以及/或是多个设备被连接,你需要使用-d,-e或是-r选项来指定要运行这条命令的目标设备。
命令-Commands
以后表格中列举了所有可用的adb命令并解析了他们的意义以及使用方法。
表 1. 可用的adb命令
排列模拟器/设备-Querying for Emulator/Device instances
在调用adb命令前,先了解有哪些模拟器/设备实例被连接到了adb服务器将会有很大的帮助。你可以使用devices这条命令来获取一个连接的模拟器/设备列表:
1 |
adb devices
|
响应之后,adb将打印出所有实例的状态信息:
- 序列号-一个由adb为每一个模拟器/实例创建的唯一标识符。通过其控制台端口号标识出一个模拟器/设备实例。其格式为-.emulator-5554是序列号的一个范例。
- 状态-一个实例的连接状态可能为以下之一:
- 离线(offline)-这个实例没有连接到adb或是无响应
- 设备(device)-这个实例现在再连接到adb服务器。注意,这个状态并不表明此Android系统已经完全启动并可以操作,因为,当设备还在启动过程时,就已经与adb建立连接了。然后,当启动后,这是一个模拟器/设备实例的正常的可操作状态。
- 无设备(no device)-没有模拟器/设备实例与adb连接。
每一个实例信息的输出格式如下:
1 |
[serialNumber] [state]
|
以下是使用devices命令及其输出结果的一个范例:
1 2 3 4 5 |
adb devices
List of devices attached
emulator-5554 device
emulator-5556 device
emulator-5558 device
|
将命令输送到指定的模拟器/设备实例上-Directing Commands to a Specific Emulator/Device instance
如果有多个模拟器/设备实例下在运行,当调用adb命令时,你必需指定一个目标实例。使用命令中的-s选项来完成。其使用方式如下:
1 |
adb -s <serialNumber> <command>
|
如上所述,使用adb赋予的序列号为一条命令指定目标实例。你可以使用devices命令来获取下在运行的模拟器/设备实例的序列号。例如:
1 |
adb -s emulator-5556 install helloWorld.apk
|
注意,当多个模拟器/设备在运行时,如果你没有为adb命令指定一个目标实例,adb将摄报错。
如果你有多个设备可用(硬件的或是模拟的),但只有一个模拟器,只需要简单地使用-e选项将命令输送到模拟器上。同样地,如果多个可用设备中只且个是硬件设备,则可以使用-d选项将命令输送到硬件设备上。
安装一个应用程序-Installing an Application
你可以使用adb将一个应用程序从你的开发电脑上复制并安装到一个模拟器/设备上。使用install命令可以完成这个功能。在这个命令中,你必须指明这个.apk文件的路径:
1 |
adb install <path_to_apk>
|
更多关于如果创建一个你可以用来在模拟器或设备实例上安装的.apk文件的信息,请见 创建并运行-Building and Running。
注意,如果你使用的时Eclipse开发环境,并且安装了ADT插件,你并不需要使用直接adb(或是aapt)来为你的模拟器/设备实例安装应用程序。取而代之的是,ADT为你处理了打包并安装的所有操作。
代理端口-Forwarding Ports
你可以使用forward命令来建立任意端口的代理-将一个任意的主机端口上的请求转发到另一个在不同端口上的模拟器/设备实例上。以下是一个建立代理的范例,其将主机端口号为6100上的请求转发到了在7100端口上的模拟器/设备上:
1 |
adb forward tcp:6100 tcp:7100
|
你也可以使用adb为指定的抽象地UNIX域套接字建立代理,如:
1 |
adb forward tcp:6100 local:logd
|
将文件复制到模拟器/设备实例上,或是从模拟器/设备实例上复制文件-Copying Files to or from an Emulator/Device Instance
你可以使用adb命令pull和push来将文件复制到模拟器/设备实例上,或是从模拟器/设备上复制出文件。不同于install命令(将APK文件复制到指定的路径),pull和push命令可以让你复制任意路径的文件,或是复制文件到模拟器/设备上的任务位置。
从模拟器或设备上复制一个文件或目录(及其子目录),使用:
1 |
adb pull <remote> <local>
|
复件一个文件或目录(及其子目录)到模拟器或设备上,使用:
1 |
adb push <local> <remote>
|
在这些命令中和分别代表了目标文件/目录在你的开发机器(local)和模拟器/设备实例(remote)上的路径。例如:
1 |
adb push foo.txt /sdcard/foo.txt
|
调用Shell命令-Issuing Shell Commands
Adb提供了一个Unix shell,它允许你在模拟器或是连接地设备上运行各种命令。这些命令的二进制文件存在于模拟器或设备的文件系统中,在/system/bin/...目录下。
两个最常用的工具是activity manager 和 [package manager] (pm)。
你可以adb命令加入shell 命令来决定是否进入模拟器/设备的adb远程shell中。调用一条命令,且不进入远程shell,其shell命令格式如下:
1 |
adb[-d|-e|-s <serialNumber>] shell <shell_command>
|
进入模拟器/设备上的远程shell,其格式为:
1 |
adb[-d|-e|-s <serialNumber>] shell
|
当你准备好退出远程shell时,可以按CTRL+D或是输入exit.
使用窗口管理器-Using activity manager(am)
在adb shell中,你可以通过窗口管理器(am)工具调用命令,它可以让你执行各种系统动作,如,启动一个窗口,强制停止一个进程,广播一个Intent,修改设备屏幕属性等等。在一个shell中,其语法为:
1 |
adm <command>
|
你也可以在adb中直接调用窗口管理命令而不进入远程shell,例如:
1 |
adb shell am start -a android.intent.action.VIEW
|
表 2.可用的窗口管理命令
参数详解
对于使用了参数的窗口管理命令,你可以其intent为以下选项之一:
-
-a < ACTION >
指定intent动作,例如“android.intent.action.VIEW”。这个参数只能申明一次。
-
-d < DATA_URI >
指定intent数据URI,例如:“content://contacts/pelple/1”。这个参数只能申明一次。
-
-t < MIME_TYPE >
指定intent MIME类型,例如:"image/png"。这个参数只能申明一次
-
-c < CATEGORY >
指定一个intent分类,例如:"android.intent.category.APP_CONTACTS"。
-
-n < COMPONENT >
指定组件名称及包名前缀,用来构建一个显性的intent,例如:“com.example.app/.ExampleActivity”。
-
-f < FLAGS 〉
为intent添加标志位,同setFlags())。
-
--esn < EXTRA_KEY >
附加一个空值,这个选项不支持URI intents。
-
-e|--es < EXTRA_KEY > < EXTRA_STRING_VALUE >
添加一个字符串类型的键-值对数据。
-
--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>
添加一个URI类型的键-值对数据。
-
--ecn < EXTRA_KEY > < EXTRA_COMPONENT_NAME_VALUE >
添加一个组件名称,其已转化,并作为ComponentName对象传递。
-
--eia < EXTRA_KEY > < EXTRA_INT_VALUE >[,<EXTRA_INT_VALUE...]
添加一个整型数组。
-
--ela < EXTRA_KEY > < EXTRA_LONG_VALUE >[,<EXTRA_LONG_VALUE...]
添加一个长整型数组。
-
--efa < EXTRA_KEY > < EXTRA_FLOAT_VALUE >[,<EXTRA_FLOAT_VALUE...]
添加一个浮点型数组。
-
--grant-read-uri-permission
-
--grant-write-uri-permission
-
--debug-log-resolution
-
--exclude-stopped-packages
-
--include-stopped-packages
-
--activity-brought-to-front
-
--activity-clear-top
包含FLAG_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
包含FLAG_ACTIVITY_NO_HISTORY标志位。
-
--activity-no-user-action
-
--activity-previous-is-top
-
--activity-reorder-to-front
-
--activity-reset-task-if-needed
-
--activity-single-top
包含FLAG_ACTIVITY_SINGLE_TOP标志位。
-
--activity-clear-task
包含FLAG_ACTIVITY_CLEAR_TASK标志位。
-
--activity-task-on-home
-
--receiver-registered-only
-
--receiver-replace-pending
-
--selector
要求使用-d和-t选项来设置intent数据及类型。
-
< URI > < COMPONENT > < PACKAGE >
当你没有使用以上的选项时,你也可以直接指定一个URI,包名,和组件名。当一个参数没有修饰限制时,如果它包含了“:”(冒号),则系统将假设其参数为URI,包含“/”(前向斜杆)时,假设参数为组件名,其它情况则假设为包名。
使用包管理-Using Package manager(pm)
在adb shell中,你可以使用包管理来工具来调用adb命令,来执行在设备上安装应用程序包或查寻已安装包的功能。在shell中,其语法如下:
1 |
pm <command>
|
你也可以在adb中调用包管理命令而不进入远程的shell,例如:
1 |
adb shell pm uninstall com.example.MyApp
|
表 3. 可用的包命令
通过远程shell检查sqlite3数据库-Examining sqlite3 databases from a remote shell
通过adb远程shell,你可以使用sqlite3命令行程序来管理由Android应用程序创建的SQLite数据库。Sqlite3工具包含了许多有用的命令,例如 .dump可以用来打印出一个表中的内容,.schema可以用来打印一个已存在的表的SQL CREATE描述。 这个工具也可以让你在运行中执行SQLite命令。
要使用sqlite3命令,首先进入一个模拟器实例的远程shell(如前文所述),然后使用sqlite3命令调用这个工具。当调用sqlite3时,你也可以选择指定你想要探寻的数据库的完整路径。模拟器/设备实例将SQLite3数据库存放在/data/data//databases/文件下。
以下是一个范例:
1 2 3 4 5 6 |
adb -s emulator-5554 shell
# sqlite3 /data/data/com.example.google.rss.rssexample/data/bases/rssitems.db
SQLite version 3.3.12
Enter ".help" for instructions
.... enter commands, then quit...
sqlite> .exit
|
当你调用sqlite3之后,你就可以在shell中执行sqlite3命令。使用exit或CTRL+D来退出并返回到adb远程shell中。
UI/应用程序训练猴-UI/Application Exerciser Monkey
Monkey 是运行在模拟器或是设备上的一个程序,并产生用户事件伪随机流,如点击(clicks),触摸(touches),手势(gestures),以及一系列的系统级事件。你可以使用Monkey程序为你正在开发的应用在一个随机但可重复的方式下进行压力测试。
最简单的使用Monkey程序的方法是调用以下命令。这条命令将启动你的应用,并向其发送500次伪随机事件。
1 |
adb shell monkey -v -p your.package.name 500
|
更多关于Monkey程序的命令选项信息,请见完整的UI/Application Exerciser Monkey文档。
其它shell命令-Other shell commands
使用以后命令查看所有可用的shell命令:
1 |
adb shell ls /system/bin
|
对于大多数的命令,帮助都是可用的。
表4列举了一些更常见的adb shell命令。
表 4. 其它一些adb shell 命令
启用logcat日志-Enabling logcat logging
Android日志系统提供了一种收集并查看系统调试输出信息的机制。来自于各种应用程序或是系统不同部分的日志信息被一系列循环缓存所收集,这些信息可以通过logcat命令查看并过滤。
你可以使用logcat命令来查看并跟踪系统日志缓存中的内容,一般的用法如下:
1 |
[adb] logcat [option] ... [filter-spec] ...
|
你可以在你开发的电脑上或是从模拟器/设备实例上的远程adb shell中使用logcat命令。看你开发的电脑上查看日志输入信息,你可以使用:
1 |
adb logcat
|
在远程adb shell中,你可以使用:
1 |
logcat
|
更多关于logcat命令选项及过滤说明的完整信息,请见日志的读与写-Reading and Writing Logs。
停止adb服务器
在某些情况下,你可能会需要停止adb服务器进程并重启。例如,如果adb不响应命令时,你可以停止服务器并重启它,这样可能就能解决这个问题。
使用kill-server命令停止adb服务器,然后,你可以通过调用其它任何adb命令来重启服务器。