Android 工具-adb

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android 开发中, adb 是开发者经常使用的工具,是 Android 开发者必须掌握的。

Android Debug Bridge,Android 调试桥接器,简称 adb ,该工具位于 <sdk>/platform-tools/ 目录下,其源码位于 <path-to-sourcecode>/system/core/adb 目录下,是用于管理模拟器或真机状态的万能工具。 adb 采用了客户端-服务器模型,包括三个部分:

  1. 客户端部分,运行在开发用的电脑上,可以在命令行中运行adb命令来调用该客户端,像 DDMS 这样的 Android 工具也可以调用 adb 客户端。
  2. 守护进程部分,运行于模拟器或手机的后台。
  3. 服务端部分,是运行在开发用电脑上的后台进程,用于管理客户端与运行在模拟器或真机的守护进程通信。

adb 工具模型示意图如下:

adb 的工作原理

当启动 adb 客户端时,客户端首先检查 adb 服务端进程是否运行,如果没有运行,则启动服务端。当服务端启动时,它会绑定到本地的 TCP5037 端口,并且监听从 adb 客户端发来的命令——所有 adb 客户端都使用 5037 端口与 adb 服务端通信。

接下来服务端与所有正在运行的模拟器或手机连接。它通过扫描 5555-5585 之间的奇数号端口来搜索模拟器或手机,一旦发现 adb 守护进程,就通过此端口进行连接。需要说明的是,每一个模拟器或手机使用一对有序的端口,偶数号端口用于控制台连接,奇数号端口用于 adb 连接,例如:

Emulator 1, console: 5554
Emulator 1, adb: 5555
Emulator 2, console: 5556
Emulator 2, adb: 5557 ...

即如果模拟器与 adb 在 5555 端口连接,则其与控制台的连接就是 5554 端口。

当服务端与所有的模拟器建立连接之后,就可以使用 adb 命令来控制或者访问了。因为服务端管理着连接并且可以接收到从多个 adb 客户端的命令,所以可以从任何一个客户端或脚本来控制任何模拟器或手机设备。

补充

  1. 使用 adb 命令调试需要手机开启 开发者模式 下的 USB 调试,在 Android 4.2 及更高的版本中,开发者选项默认是隐藏的,你可以去 设置——>关于手机 ,然后连续点击七次版本号即可。返回上层就可以在底部看见 开发者模式 了。当然有些定制的 ROM 开启方式会有点不一样,这个就要去问 ROM 的开发者了。

  2. 关于 USB 调试与计算机的 RSA 密钥指纹配对。Google 官方原文如下:

    When you connect a device running Android 4.2.2 or higher to your computer, the system shows a dialog asking whether to accept an RSA key that allows debugging through this computer. This security mechanism protects user devices because it ensures that USB debugging and other adb commands cannot be executed unless you're able to unlock the device and acknowledge the dialog. This requires that you have adb version 1.0.31 (available with SDK Platform-tools r16.0.1 and higher) in order to debug on a device running Android 4.2.2 or higher.

    大意就是,你想使用 USB调试 就得启用 USB调试 模式下的 RSA密钥指纹。不然我就不给你用。

  3. 关于使用真机调试的更多信息可参考:Run Apps on a Hardware Device

adb 用法

查询模拟器或手机状态

了解 adb 服务端连接的模拟器或手机可以帮助更好的使用 adb 命令,这可以通过 devices 命令来列举当前连接的设备:

adb devices

执行结果是 adb 为每一个设备输出以下状态信息:

序列号(serialNumber):由 adb 创建用于唯一标识设备的字符串,格式是 <设备类型>-<端口号>,例如: emulator-5554

连接状态(state),其值是可能是下面的任意一种:

offline — 未连接或未响应

device — 表示设备已经连接到服务端。但需要注意的是,这个状态并不表示 Android 系统已经完全启动起来并且可操作,因为系统在启动的过程中就已经连接 adb ,但这个状态是正常的可操作状态。

no device - 表示没有任何设备连接(楼主测试过程中没有碰到过 no device 的情况,没连接设备就没任何输出)

每一个设备的输出形如:

[serialNumber] [state]

下面是 adb devices 命令和其执行结果:

$ adb devices
List of devices attached
emulator-5554 device
emulator-5556 device
emulator-5558 device

如果没有模拟器或手机在运行,运行 adb devices 命令的执行结果如下:

$ adb devces
List of devices attached

操作指定模拟器或手机

如果有多个模拟器或手机正在运行,当使用 adb 命令的时候就需要指定目标设备,这可以通过使用 -s 选项参数实现,用法如下:

adb -s <serialNumber> <command>

你可以使用 adb 命令指定序列号在特定的设备上执行命令,这里可以先使用前面提到的 adb devices 命令查询设备的序列号信息。

例如:

adb -s emulator-5556 install helloWorld.apk

需要注意的是,如果使用了 -s 而没有指定设备的话, adb 会报错。

补充

这是 Google 官方给出在多设备的情况下,不用 -s 参数指定目标设备的快捷方式,原文如下:

If you have multiple devices available (hardware or emulated), but only one is an emulator, simply use the -e option to send commands to the emulator. Likewise if there's multiple devices but only one hardware device attached, use the -d option to send commands to the hardware device.

大意就是:如果你有多个设备,即既有模拟器,又有真机,但是模拟器只有一个,那么你可以使用 -e 参数想模拟器发送命令,用法如下:

$ adb -e install helloWorld.apk
//同理,如果有多个设备,但只有一个真机,可以使用如下命令快速发送命令
$ adb -d install helloWorld.apk

安装应用

使用 adb install 命令可以从开发用电脑中复制应用程序并且安装到模拟器或手机上,adb install 命令必须指定待安装的.apk文件的路径:

adb install [-lrtsdg] <path_to_apk>
(-l: 锁定该程序)
(-r: 重新安装该程序,保留应用数据)
(-t: allow test packages)
(-s: 将应用安装到 SD卡,不过现在手机好像都没有 SD卡 了吧)
(-d: 允许降版本号安装,当然只有 debug 包才能使用)
(-g: 安装完默认授予所有运行时权限,这个应该对 Android 6.0 及之后的版本才有效吧)

更多关于创建 apk 文件可参考:Build And Running

卸载应用

既然有安装应用的命令,那当然有卸载应用的命令。卸载应用命令的格式如下:

//<package> 表示要卸载应用的包名
adb uninstall [-k] <package>
(-k:不删除程序运行所产生的数据和缓存目录)

端口转发

使用 adb forward 命令转发端口 — 将特定端口上的请求转发到模拟器或手机的不同的端口上。下例是从 6100端口 转到 7100端口 :

adb forward tcp:6100 tcp:7100

也可以使用UNIX命名的socket标识:

adb forward tcp:6100 local:logd

补充:关于 adb forward 命令的作用不是很明白,网上搜了下,大部分文章都是转载了 浅析 adb 命令 - adb forward ,不知道这是不是原文,反正看不得不是很明白。有哪位大神能跟我讲讲嘛?

与模拟器或手机传输文件

使用 adb 命令 pullpush 能从 Android 设备拷贝或复制文件到 Android 设备。跟 install 命令不同,pullpush 命令允许拷贝和复制文件到任何位置。

从模拟器或手机拷贝文件或文件夹(包括文件夹的子目录)

adb pull [-a] <remote_path> <local_path>
(-a:保留文件时间戳及属性)

将文件或文件夹(包括文件夹的子目录)拷贝到模拟器或手机

adb push <local_path> <remote_path>

比如,我想把桌面的 log.txt 复制到手机的 dev 目录下,则命令如下:

$ adb push /Users/littlejie/Desktop/log.txt /dev

有时候,使用该命令复制文件到手机或从手机复制文件,会碰到如下提示:

failed to copy 'log.txt' to '/dev/log.txt': Permission denied

备注: Permission denied 这个问题以前在使用 Windows 系统的时候碰到过,现在转 Mac 后就没有再遇到,难道是我打开方式不对嘛?再补充一点, Mac 上我运行 adb root 命令真的有点一头雾水,因为竟然提示:

$ adb root
adbd is already running as root

这是因为当前用户没有相应的权限或者是 /dev 目录不可写。解决方法如下:

//方法一
//已 root 权限启动 adb 服务
$ adb root
//adb remount (重新挂载系统分区,使系统分区重新可写)
$ adb remount
//将文件复制到 /dev 目录下
$ adb push /Users/littlejie/Desktop/log.txt /dev
//方法二:修改文件的读写权限
$ adb shell
# su
# chmod 777 /dev

关于 Linux 下文件权限的更多内容请参考:linux系统644、755、777权限详解

adb shell

这里简单讲一下 adb shell 的使用,因为 adb shell 的用法太多,功能太强,完全可以专门分出一篇文章来记录不出意外,下周应该能写完有兴趣的同学可以自己先去看 Google 的官方文档:ADB Shell Commands

adb shell 有两种使用方式,一种是不进入 remote shell 直接执行命令行,格式如下:

adb [-d|-e|-s <serialNumber>] shell <shell_command>

还有一种是,进入模拟器或手机的 remote shell 执行,格式如下:

adb [-d|-e|-s <serialNumber>] shell

开启或关闭 adb 服务

在某些情况下需要重启 adb 服务来解决问题,比如 adb 无响应。这时你可以通过 adb kill-server 来实现这一操作。

之后,通过 adb start-server 或者任意 adb 命令来重启 adb 服务。

$ adb kill-server
$ adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully * $ adb kill-server
$ adb devices
List of devices attached
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
emulator-5556 device
emulator-5554 device

无线调试

平时我们都是使用 USB调试,但是现在也支持通过 WIFI 进行调试了。使用方式如下:

  1. 首先,你要将 Android 设备和 装有 adb 的电脑连接到同一 Wi-Fi 网络。其次,你需要配置好防火墙,否则很有可能导致 Wi-Fi 调试不能使用。

  2. 使用 USB数据线 将手机连接到电脑。

  3. 设置目标设备监听 5555端口 的 TCP/IP 连接。

    $ adb tcpip 5555
  4. 断开手机与电脑的 USB 连接。

  5. 查看手机的 IP地址 。例如,在 Nexus 设备上,你可以通过如下方式查看: 设置——>关于手机——>状态——>IP地址。在 Androir Wear 上,你可以通过如下方式查看:设置——>Wi-Fi设置——>高级——>IP地址

  6. 通过 IP 连接手机

    adb connect <device_ip_address>
  7. 确认手机是否连接到电脑上

    $ adb devices
    List of devices attached
    <device-ip-address>:5555 device

通过以上步骤,就可以开心的享用 WiFi 调试了。如果没有正常连接,可以按照下面的步骤检查:

  1. 检查电脑和手机是否还在同一个 WiFi 网络下
  2. 重新执行一次 adb connect <device_ip_address> 命令
  3. 重启 adb 服务,然后重头再来
  4. 检查是否是防火墙的设置问题

这是一篇关于 Android 设备 USB调试 和 WiFi调试 相互切换 的博文,博主写了一个脚本来实现这个过程,有兴趣的同学可以去看看。

补充

  • 获取设备序列号

    $ adb shell
    emulator-5554
  • 查看 bugreport 报告

    //直接在终端输出
    $ adb bugreport
    //将 bugreport 输出到指定文件
    $ adb bugreport > file_path

    adb bugreport 这个命令非常简单,但是在实际应用中非常有用,它会输出从开机之后详细的 dumpsys 、 dumpstate 和 logcat 信息,是一份完整的日志记录。对分析用户行为、异常信息、系统状态有很大的参考作用。一般我们会把 bugreport 导出到电脑上分析。

    bugreport 的详细使用可以参考 Baniel01 的这篇 Android adb bugreport工具分析和使用 文章,里面有很详细的介绍。

  • 查看设备的 log

    $ adb logcat
  • 查看 adb 的帮助

    这个命令很简单,但是也很实用,如果你不知道该使用哪个命令,那么使用 adb 帮助命令你能查看到大部分 adb 命令的作用和使用方法。

    $ adb help
  • 重启手机

    有时候,手动关机太麻烦,那就来个命令行吧~

    adb reboot
  • 以 root 权限开启 adb 守护进程

    //此命令会重启守护进程
    $ adb root
    //不以 root 权限开启 adb 守护进程
    $ adb unroot

总结

以上就是 adb 命令的常见用法,大部分翻译自 Android Debug Bridge ,其中加了一些个人总结。有些不常用的 adb 命令没有介绍,更多 adb 用法请见:Adb Command Summary。文中如有纰漏,欢迎大家留言指出。

微博:厉圣杰

微信:

参考:

  1. Android Debug Bridge
  2. 浅析 adb 命令 - adb forward
  3. Android_ADB_通过WIFI或USB方式完成调试
  4. Android adb bugreport工具分析和使用

Android 工具-adb的更多相关文章

  1. 【Xamarin挖墙脚系列:Android最重要的命令工具ADB】

    原文:[Xamarin挖墙脚系列:Android最重要的命令工具ADB] adb工具提供了很好的基于命令的对系统的控制. 以前说过,安卓的本质是运行在Linux上的虚机系统.在Linux中,对系统进行 ...

  2. Android 神兵利器—— Adb 常用命令

    总结的Android工具类文章: Android 神兵利器-- Adb 常用命令 Android 神兵利器-- Git 常用命令 Adb的全称为Android Debug Bridge,是管理andr ...

  3. Android的ADB配置环境和adb指令使用

    adb的全称为Android Debug Bridge,就是起到调试桥的作用,作为一名开发者倒是常用到这个工具.借助adb工具,我们可以管理设备或手机模拟器的状态.还可以进行很多手机操作,如安装软件. ...

  4. Android测试——adb命令

    Adb (Android Debug Bridge)起到调试桥的作用. 通过adb我们可以在Eclipse中方便通过DDMS来调试Android程序.adb采用监听Socket TCP 5554等端口 ...

  5. Android composite adb interface

    我的平板连上电脑后,在eclipse的DDMS中查看不到.很奇怪以前不会,我以为在进程中有其他的adb.exe冲突.查看任务管理器没有看到其他adb.exe进程.然后重启eclipse也不用,重启电脑 ...

  6. android的adb详解(多设备时adb调用)

    在多设备(模拟器)时,想要直接用logcat查看其中一台的状态,或者直接把应用安装到目标设备上时,需要指定设备号.adb devices这个指令可以得到当前设备的序列号(serialNumber).比 ...

  7. Linux下安装Android的adb驱动-解决不能识别的问题

    Linux下安装Android的adb驱动-解决不能识别的问题 20141011更新:      老方法对我当时使用的一款设备一直都没有出现问题,最后遇到小米手机还有Android4.4版本的系统都会 ...

  8. Android 常用 adb 命令总结

    Android 常用 adb 命令总结 针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命 ...

  9. 【Android端 adb相关】adb相关总结

    一.什么是adb? adb的全称是:Android Debug Bridge,adb命令的构成是三部分,分别是:服务器.客户端.后台程序: (1)客户端:一个在PC上运行的客户端.可以通过shell端 ...

随机推荐

  1. C语言 · 矩形面积交

    问题描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴.对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积. 输入格式 输入仅包含两行,每行描述一个矩形. 在每行中 ...

  2. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  3. Android 判断一个 View 是否可见 getLocalVisibleRect(rect) 与 getGlobalVisibleRect(rect)

    Android 判断一个 View 是否可见 getLocalVisibleRect(rect) 与 getGlobalVisibleRect(rect) [TOC] 这两个方法的区别 View.ge ...

  4. 在Linux配置Nginx web服务器步骤

    系统环境:centos7 需要软件:nginx-1.3.16.tar.gz   libevent-2.0.21-stable.tar.gz  Pcre 和 pcre-devel nginx下载地址:h ...

  5. 修改MySQL默认字符集编码

    好记心不如烂笔头,很多东西当时没记下来,过了就忘了,下次用到时又得浪费好多时间才能解决.今天又遇到修改MySQL默认字符集编码的问题,折腾了半天解决了,赶快记录下来,以后就不用每次折腾了. 查看MyS ...

  6. 技术笔记:Delphi多线程应用读写锁

    在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...

  7. Xamarin.Android之SQLiteOpenHelper

    一.前言 在手机中进行网络连接不仅是耗时也是耗电的,而耗电却是致命的.所以我们就需要数据库帮助我们存储离线数据,以便在用户未使用网络的情况下也可以能够使用应用的部分功能,而在需要网络连接的功能上采用提 ...

  8. 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能

    前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...

  9. Angular移除不必要的$watch之性能优化

    双向绑定是Angular的核心概念之一,它给我们带来了思维方式的转变:不再是DOM驱动,而是以Model为核心,在View中写上声明式标签.然后,Angular就会在后台默默的同步View的变化到Mo ...

  10. 用Go实现的简易TCP通信框架

    接触到GO之后,GO的网络支持非常令人喜欢.GO实现了在语法层面上可以保持同步语义,但是却又没有牺牲太多性能,底层一样使用了IO路径复用,比如在LINUX下用了EPOLL,在WINDOWS下用了IOC ...