ADB 用法大全

olnx6079 2年前
   <h2>基本用法</h2>    <h3>命令语法</h3>    <p>adb 命令的基本语法如下:</p>    <pre>  adb [-d|-e|-s <serialNumber>] <command></pre>    <p>如果只有一个设备/模拟器连接时,可以省略掉 <code>[-d|-e|-s <serialNumber>]</code> 这一部分,直接使用 <code>adb <command></code>。</p>    <h3>为命令指定目标设备</h3>    <p>如果有多个设备/模拟器连接,则需要为命令指定目标设备。</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>-d</td>       <td>指定当前唯一通过 USB 连接的 Android 设备为命令目标</td>      </tr>      <tr>       <td>-e</td>       <td>指定当前唯一运行的模拟器为命令目标</td>      </tr>      <tr>       <td><code>-s <serialNumber></code></td>       <td>指定相应 serialNumber 号的设备/模拟器为命令目标</td>      </tr>     </tbody>    </table>    <p>在多个设备/模拟器连接的情况下较常用的是 <code>-s <serialNumber></code> 参数,serialNumber 可以通过 <code>adb devices</code> 命令获取。如:</p>    <pre>  $ adb devices    List of devices attached  cf264b8f    device  emulator-5554   device</pre>    <p>输出里的 <code>cf264b8f</code> 和 <code>emulator-5554</code> 即为 serialNumber。比如这时想指定 <code>cf264b8f</code> 这个设备来运行 adb 命令获取屏幕分辨率:</p>    <pre>  adb -s cf264b8f shell wm size</pre>    <p>遇到多设备/模拟器的情况均使用这几个参数为命令指定目标设备,下文中为简化描述,不再重复。</p>    <h3>启动/停止</h3>    <p>启动 adb server 命令:</p>    <pre>  adb start-server</pre>    <p>(一般无需手动执行此命令,在运行 adb 命令时若发现 adb server 没有启动会自动调起。)</p>    <p>停止 adb server 命令:</p>    <pre>  adb kill-server</pre>    <h3>查看 adb 版本</h3>    <p>命令:</p>    <pre>  adb version</pre>    <p>示例输出:</p>    <pre>  Android Debug Bridge version 1.0.32  Revision 09a0d98bebce-android</pre>    <h3>以 root 权限运行 adbd</h3>    <p>adb 的运行原理是 PC 端的 adb server 与手机端的守护进程 adbd 建立连接,然后 PC 端的 adb client 通过 adb server 转发命令,adbd 接收命令后解析运行。</p>    <p>所以如果 adbd 以普通权限执行,有些需要 root 权限才能执行的命令无法直接用 <code>adb xxx</code> 执行。这时可以 <code>adb shell</code> 然后<code>su</code> 后执行命令,也可以让 adbd 以 root 权限执行,这个就能随意执行高权限命令了。</p>    <p>命令:</p>    <pre>  adb root</pre>    <p>正常输出:</p>    <pre>  restarting adbd as root</pre>    <p>现在再运行 <code>adb shell</code>,看看命令行提示符是不是变成 <code>#</code> 了?</p>    <p>有些手机 root 后也无法通过 <code>adb root</code> 命令让 adbd 以 root 权限执行,比如三星的部分机型,会提示 <code>adbd cannot run as root in production builds</code>,此时可以先安装 adbd Insecure,然后 <code>adb root</code> 试试。</p>    <p>相应地,如果要恢复 adbd 为非 root 权限的话,可以使用 <code>adb unroot</code> 命令。</p>    <h3>指定 adb server 的网络端口</h3>    <p>命令:</p>    <pre>  adb -P <port> start-server</pre>    <p>默认端口为 5037。</p>    <h2>设备连接管理</h2>    <h3>查询已连接设备/模拟器</h3>    <p>命令:</p>    <pre>  adb devices</pre>    <p>输出示例:</p>    <pre>  List of devices attached  cf264b8f    device  emulator-5554   device</pre>    <p>输出格式为 <code>[serialNumber] [state]</code>,serialNumber 即我们常说的 SN,state 有如下几种:</p>    <ul>     <li> <p><code>offline</code> —— 表示设备未连接成功或无响应。</p> </li>     <li> <p><code>device</code> —— 设备已连接。注意这个状态并不能标识 Android 系统已经完全启动和可操作,在设备启动过程中设备实例就可连接到 adb,但启动完毕后系统才处于可操作状态。</p> </li>     <li> <p><code>no device</code> —— 没有设备/模拟器连接。</p> </li>    </ul>    <p>以上输出显示当前已经连接了两台设备/模拟器,<code>cf264b8f</code> 与 <code>emulator-5554</code> 分别是它们的 SN。从 <code>emulator-5554</code> 这个名字可以看出它是一个 Android 模拟器。</p>    <p>常见异常输出:</p>    <ol>     <li> <p>没有设备/模拟器连接成功。</p> <pre>  List of devices attached</pre> </li>     <li> <p>设备/模拟器未连接到 adb 或无响应。</p> <pre>  List of devices attached  cf264b8f offline</pre> </li>    </ol>    <h3>USB 连接</h3>    <p>通过 USB 连接来正常使用 adb 需要保证几点:</p>    <ol>     <li> <p>硬件状态正常。</p> <p>包括 Android 设备处于正常开机状态,USB 连接线和各种接口完好。</p> </li>     <li> <p>Android 设备的开发者选项和 USB 调试模式已开启。</p> <p>可以到「设置」-「开发者选项」-「Android 调试」查看。</p> <p>如果在设置里找不到开发者选项,那需要通过一个彩蛋来让它显示出来:在「设置」-「关于手机」连续点击「版本号」7 次。</p> </li>     <li> <p>设备驱动状态正常。</p> <p>这一点貌似在 Linux 和 Mac OS X 下不用操心,在 Windows 下有可能遇到需要安装驱动的情况,确认这一点可以右键「计算机」-「属性」,到「设备管理器」里查看相关设备上是否有黄色感叹号或问号,如果没有就说明驱动状态已经好了。否则可以下载一个手机助手类程序来安装驱动先。</p> </li>     <li> <p>通过 USB 线连接好电脑和设备后确认状态。</p> <pre>  adb devices</pre> <p>如果能看到</p> <pre>  xxxxxx device</pre> <p>说明连接成功。</p> </li>    </ol>    <h3>无线连接</h3>    <p>除了可以通过 USB 连接设备与电脑来使用 adb,也可以通过无线连接——虽然连接过程中也有需要使用 USB 的步骤,但是连接成功之后你的设备就可以在一定范围内摆脱 USB 连接线的限制啦!</p>    <p>操作步骤:</p>    <ol>     <li> <p>将 Android 设备与将运行 adb 的电脑连接到同一个局域网,比如连到同一个 WiFi。</p> </li>     <li> <p>将设备与电脑通过 USB 线连接。</p> <p>应确保连接成功(可运行 <code>adb devices</code> 看是否能列出该设备)。</p> </li>     <li> <p>让设备在 5555 端口监听 TCP/IP 连接:</p> <pre>  adb tcpip 5555</pre> </li>     <li> <p>断开 USB 连接。</p> </li>     <li> <p>找到设备的 IP 地址。</p> <p>一般能在「设置」-「关于手机」-「状态信息」-「IP地址」找到。</p> </li>     <li> <p>通过 IP 地址连接设备。</p> <pre>  adb connect <device-ip-address></pre> <p>这里的 <code><device-ip-address></code> 就是上一步中找到的设备 IP 地址。</p> </li>     <li> <p>确认连接状态。</p> <pre>  adb devices</pre> <p>如果能看到</p> <pre>  <device-ip-address>:5555 device</pre> <p>说明连接成功。</p> </li>    </ol>    <p>如果连接不了,请确认 Android 设备与电脑是连接到了同一个 WiFi,然后再次执行 <code>adb connect <device-ip-address></code> 那一步;</p>    <p>如果还是不行的话,通过 <code>adb kill-server</code> 重新启动 adb 然后从头再来一次试试。</p>    <p><strong>断开无线连接</strong></p>    <p>命令:</p>    <pre>  adb disconnect <device-ip-address></pre>    <h2>应用管理</h2>    <h3>查看应用列表</h3>    <p>查看应用列表的基本命令格式是</p>    <pre>  adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]</pre>    <p>即在 <code>adb shell pm list packages</code> 的基础上可以加一些参数进行过滤查看不同的列表,支持的过滤参数如下:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>显示列表</th>      </tr>     </thead>     <tbody>      <tr>       <td>无</td>       <td>所有应用</td>      </tr>      <tr>       <td>-f</td>       <td>显示应用关联的 apk 文件</td>      </tr>      <tr>       <td>-d</td>       <td>只显示 disabled 的应用</td>      </tr>      <tr>       <td>-e</td>       <td>只显示 enabled 的应用</td>      </tr>      <tr>       <td>-s</td>       <td>只显示系统应用</td>      </tr>      <tr>       <td>-3</td>       <td>只显示第三方应用</td>      </tr>      <tr>       <td>-i</td>       <td>显示应用的 installer</td>      </tr>      <tr>       <td>-u</td>       <td>包含已卸载应用</td>      </tr>      <tr>       <td><code><FILTER></code></td>       <td>包名包含 <code><FILTER></code> 字符串</td>      </tr>     </tbody>    </table>    <p>所有应用</p>    <p>命令:</p>    <pre>  adb shell pm list packages</pre>    <p>输出示例:</p>    <pre>  package:com.android.smoketest  package:com.example.android.livecubes  package:com.android.providers.telephony  package:com.google.android.googlequicksearchbox  package:com.android.providers.calendar  package:com.android.providers.media  package:com.android.protips  package:com.android.documentsui  package:com.android.gallery  package:com.android.externalstorage  ...  // other packages here  ...</pre>    <p>系统应用</p>    <p>命令:</p>    <pre>  adb shell pm list packages -s</pre>    <p>第三方应用</p>    <p>命令:</p>    <pre>  adb shell pm list packages -3</pre>    <p>包名包含某字符串的应用</p>    <p>比如要查看包名包含字符串 <code>mazhuang</code> 的应用列表,命令:</p>    <pre>  adb shell pm list packages mazhuang</pre>    <p>当然也可以使用 grep 来过滤:</p>    <pre>  adb shell pm list packages | grep mazhuang</pre>    <h3>安装 APK</h3>    <p>命令:</p>    <pre>  adb install <apk file></pre>    <p>参数:</p>    <p><code>adb install</code> 后面可以跟一些参数来控制安装 APK 的行为,常用参数及含义如下:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>-r</td>       <td>允许覆盖安装。</td>      </tr>      <tr>       <td>-s</td>       <td>将应用安装到 sdcard。</td>      </tr>      <tr>       <td>-d</td>       <td>允许降级覆盖安装。</td>      </tr>     </tbody>    </table>    <p>完整参数列表及含义可以直接运行 <code>adb</code> 命令然后查看 <code>adb install [-lrtsdg] <file></code> 一节。</p>    <p>如果见到类似如下输出(状态为 <code>Success</code>)代表安装成功:</p>    <pre>  12040 KB/s (22205609 bytes in 1.801s)          pkg: /data/local/tmp/SogouInput_android_v8.3_sweb.apk  Success</pre>    <p>而如果状态为 <code>Failure</code> 则表示安装失败。常见安装失败输出代码、含义及可能的解决办法如下:</p>    <table>     <thead>      <tr>       <th>输出</th>       <th>含义</th>       <th>解决办法</th>      </tr>     </thead>     <tbody>      <tr>       <td>INSTALL_FAILED_ALREADY_EXISTS</td>       <td>应用已经存在</td>       <td>使用 <code>-r</code> 参数</td>      </tr>      <tr>       <td>INSTALL_FAILED_INVALID_APK</td>       <td>无效的 APK 文件</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_INVALID_URI</td>       <td>无效的 APK 文件名</td>       <td>确保 APK 文件名里无中文</td>      </tr>      <tr>       <td>INSTALL_FAILED_INSUFFICIENT_STORAGE</td>       <td>空间不足</td>       <td>清理空间</td>      </tr>      <tr>       <td>INSTALL_FAILED_DUPLICATE_PACKAGE</td>       <td>已经存在同名程序</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_NO_SHARED_USER</td>       <td>请求的共享用户不存在</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_UPDATE_INCOMPATIBLE</td>       <td>已经安装过签名不一样的同名应用,且数据没有移除</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_SHARED_USER_INCOMPATIBLE</td>       <td>请求的共享用户存在但签名不一致</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_MISSING_SHARED_LIBRARY</td>       <td>安装包使用了设备上不可用的共享库</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_REPLACE_COULDNT_DELETE</td>       <td>替换时无法删除</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_DEXOPT</td>       <td>dex 优化验证失败或空间不足</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_OLDER_SDK</td>       <td>设备系统版本低于应用要求</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_CONFLICTING_PROVIDER</td>       <td>设备里已经存在与应用里同名的 content provider</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_NEWER_SDK</td>       <td>设备系统版本高于应用要求</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_TEST_ONLY</td>       <td>应用是 test-only 的,但安装时没有指定 <code>-t</code>参数</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_CPU_ABI_INCOMPATIBLE</td>       <td>包含不兼容设备 CPU 应用程序二进制接口的 native code</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_MISSING_FEATURE</td>       <td>应用使用了设备不可用的功能</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_CONTAINER_ERROR</td>       <td>sdcard 访问失败</td>       <td>确认 sdcard 可用,或者安装到内置存储</td>      </tr>      <tr>       <td>INSTALL_FAILED_INVALID_INSTALL_LOCATION</td>       <td>不能安装到指定位置</td>       <td>切换安装位置,添加或删除<code>-s</code> 参数</td>      </tr>      <tr>       <td>INSTALL_FAILED_MEDIA_UNAVAILABLE</td>       <td>安装位置不可用</td>       <td>一般为 sdcard,确认 sdcard 可用或安装到内置存储</td>      </tr>      <tr>       <td>INSTALL_FAILED_VERIFICATION_TIMEOUT</td>       <td>验证安装包超时</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_VERIFICATION_FAILURE</td>       <td>验证安装包失败</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_PACKAGE_CHANGED</td>       <td>应用与调用程序期望的不一致</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_UID_CHANGED</td>       <td>以前安装过该应用,与本次分配的 UID 不一致</td>       <td>清除以前安装过的残留文件</td>      </tr>      <tr>       <td>INSTALL_FAILED_VERSION_DOWNGRADE</td>       <td>已经安装了该应用更高版本</td>       <td>使用 <code>-d</code> 参数</td>      </tr>      <tr>       <td>INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE</td>       <td>已安装 target SDK 支持运行时权限的同名应用,要安装的版本不支持运行时权限</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_NOT_APK</td>       <td>指定路径不是文件,或不是以 <code>.apk</code> 结尾</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_BAD_MANIFEST</td>       <td>无法解析的 AndroidManifest.xml 文件</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION</td>       <td>解析器遇到异常</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_NO_CERTIFICATES</td>       <td>安装包没有签名</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES</td>       <td>已安装该应用,且签名与 APK 文件不一致</td>       <td>先卸载设备上的该应用,再安装</td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING</td>       <td>解析 APK 文件时遇到<code>CertificateEncodingException</code></td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME</td>       <td>manifest 文件里没有或者使用了无效的包名</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID</td>       <td>manifest 文件里指定了无效的共享用户 ID</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_MANIFEST_MALFORMED</td>       <td>解析 manifest 文件时遇到结构性错误</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_PARSE_FAILED_MANIFEST_EMPTY</td>       <td>在 manifest 文件里找不到找可操作标签(instrumentation 或 application)</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_INTERNAL_ERROR</td>       <td>因系统问题安装失败</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_USER_RESTRICTED</td>       <td>用户被限制安装应用</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_DUPLICATE_PERMISSION</td>       <td>应用尝试定义一个已经存在的权限名称</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_FAILED_NO_MATCHING_ABIS</td>       <td>应用包含设备的应用程序二进制接口不支持的 native code</td>       <td> </td>      </tr>      <tr>       <td>INSTALL_CANCELED_BY_USER</td>       <td>应用安装需要在设备上确认,但未操作设备或点了取消</td>       <td>在设备上同意安装</td>      </tr>      <tr>       <td>INSTALL_FAILED_ACWF_INCOMPATIBLE</td>       <td>应用程序与设备不兼容</td>       <td> </td>      </tr>      <tr>       <td>does not contain AndroidManifest.xml</td>       <td>无效的 APK 文件</td>       <td> </td>      </tr>      <tr>       <td>is not a valid zip file</td>       <td>无效的 APK 文件</td>       <td> </td>      </tr>      <tr>       <td>Offline</td>       <td>设备未连接成功</td>       <td>先将设备与 adb 连接成功</td>      </tr>      <tr>       <td>unauthorized</td>       <td>设备未授权允许调试</td>       <td> </td>      </tr>      <tr>       <td>error: device not found</td>       <td>没有连接成功的设备</td>       <td>先将设备与 adb 连接成功</td>      </tr>      <tr>       <td>protocol failure</td>       <td>设备已断开连接</td>       <td>先将设备与 adb 连接成功</td>      </tr>      <tr>       <td>Unknown option: -s</td>       <td>Android 2.2 以下不支持安装到 sdcard</td>       <td>不使用 <code>-s</code> 参数</td>      </tr>      <tr>       <td>No space left on devicerm</td>       <td>空间不足</td>       <td>清理空间</td>      </tr>      <tr>       <td>Permission denied ... sdcard ...</td>       <td>sdcard 不可用</td>       <td> </td>      </tr>     </tbody>    </table>    <p>参考:<a href="/misc/goto?guid=4959677439605494834">PackageManager.java</a></p>    <h3>卸载应用</h3>    <p>命令:</p>    <pre>  adb uninstall [-k] <packagename></pre>    <p><code><packagename></code> 表示应用的包名,<code>-k</code> 参数可选,表示卸载应用但保留数据和缓存目录。</p>    <p>命令示例:</p>    <pre>  adb uninstall com.qihoo360.mobilesafe</pre>    <p>表示卸载 360 手机卫士。</p>    <h3>清除应用数据与缓存</h3>    <p>命令:</p>    <pre>  adb shell pm clear <packagename></pre>    <p><code><packagename></code> 表示应用名包,这条命令的效果相当于在设置里的应用信息界面点击了「清除缓存」和「清除数据」。</p>    <p>命令示例:</p>    <pre>  adb shell pm clear com.qihoo360.mobilesafe</pre>    <p>表示清除 360 手机卫士的数据和缓存。</p>    <h3>查看前台 Activity</h3>    <p>命令:</p>    <pre>  adb shell dumpsys activity activities | grep mFocusedActivity</pre>    <p>输出示例:</p>    <pre>  mFocusedActivity: ActivityRecord{8079d7e u0 com.cyanogenmod.trebuchet/com.android.launcher3.Launcher t42}</pre>    <p>其中的 <code>com.cyanogenmod.trebuchet/com.android.launcher3.Launcher</code> 就是当前处于前台的 Activity。</p>    <h2>与应用交互</h2>    <p>主要是使用 <code>am <command></code> 命令,常用的 <code><command></code> 如下:</p>    <table>     <thead>      <tr>       <th>command</th>       <th>用途</th>      </tr>     </thead>     <tbody>      <tr>       <td><code>start [options] <INTENT></code></td>       <td>启动 <code><INTENT></code> 指定的 Activity</td>      </tr>      <tr>       <td><code>startservice [options] <INTENT></code></td>       <td>启动 <code><INTENT></code> 指定的 Service</td>      </tr>      <tr>       <td><code>broadcast [options] <INTENT></code></td>       <td>发送 <code><INTENT></code> 指定的广播</td>      </tr>      <tr>       <td><code>force-stop <packagename></code></td>       <td>停止 <code><packagename></code> 相关的进程</td>      </tr>     </tbody>    </table>    <p><code><INTENT></code> 参数很灵活,和写 Android 程序时代码里的 Intent 相对应。</p>    <p>用于决定 intent 对象的选项如下:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td><code>-a <ACTION></code></td>       <td>指定 action,比如 <code>android.intent.action.VIEW</code></td>      </tr>      <tr>       <td><code>-c <CATEGORY></code></td>       <td>指定 category,比如 <code>android.intent.category.APP_CONTACTS</code></td>      </tr>      <tr>       <td><code>-n <COMPONENT></code></td>       <td>指定完整 component 名,用于明确指定启动哪个 Activity,如 <code>com.example.app/.ExampleActivity</code></td>      </tr>     </tbody>    </table>    <p><code><INTENT></code> 里还能带数据,就像写代码时的 Bundle 一样:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td><code>--esn <EXTRA_KEY></code></td>       <td>null 值(只有 key 名)</td>      </tr>      <tr>       <td><code>-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE></code></td>       <td>string 值</td>      </tr>      <tr>       <td><code>--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE></code></td>       <td>boolean 值</td>      </tr>      <tr>       <td><code>--ei <EXTRA_KEY> <EXTRA_INT_VALUE></code></td>       <td>integer 值</td>      </tr>      <tr>       <td><code>--el <EXTRA_KEY> <EXTRA_LONG_VALUE></code></td>       <td>long 值</td>      </tr>      <tr>       <td><code>--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE></code></td>       <td>float 值</td>      </tr>      <tr>       <td><code>--eu <EXTRA_KEY> <EXTRA_URI_VALUE></code></td>       <td>URI</td>      </tr>      <tr>       <td><code>--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE></code></td>       <td>component name</td>      </tr>      <tr>       <td><code>--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]</code></td>       <td>integer 数组</td>      </tr>      <tr>       <td><code>--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]</code></td>       <td>long 数组</td>      </tr>     </tbody>    </table>    <h3>调起 Activity</h3>    <p>命令格式:</p>    <pre>  adb shell am start [options] <INTENT></pre>    <p>例如:</p>    <pre>  adb shell am start -n com.tencent.mm/.ui.LauncherUI</pre>    <p>表示调起微信主界面。</p>    <pre>  adb shell am start -n org.mazhuang.boottimemeasure/.MainActivity --es "toast" "hello, world"</pre>    <p>表示调起 <code>org.mazhuang.boottimemeasure/.MainActivity</code> 并传给它 string 数据键值对 <code>toast - hello, world</code>。</p>    <h3>调起 Service</h3>    <p>命令格式:</p>    <pre>  adb shell am startservice [options] <INTENT></pre>    <p>例如:</p>    <pre>  adb shell am startservice -n com.tencent.mm/.plugin.accountsync.model.AccountAuthenticatorService</pre>    <p>表示调起微信的某 Service。</p>    <h3>发送广播</h3>    <p>命令格式:</p>    <pre>  adb shell am broadcast [options] <INTENT></pre>    <p>例如:</p>    <pre>  adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -n org.mazhuang.boottimemeasure/.BootCompletedReceiver</pre>    <p>表示向 <code>org.mazhuang.boottimemeasure/.BootCompletedReceiver</code> 发送一个 <code>BOOT_COMPLETED</code> 广播,这类用法在测试的时候很实用,比如某个广播的场景很难制造,可以考虑通过这种方式来发送广播。</p>    <h3>强制停止应用</h3>    <p>命令:</p>    <pre>  adb shell am force-stop <packagename></pre>    <p>命令示例:</p>    <pre>  adb shell am force-stop com.qihoo360.mobilesafe</pre>    <p>表示停止 360 安全卫士的一切进程与服务。</p>    <h2>文件管理</h2>    <h3>复制设备里的文件到电脑</h3>    <p>命令:</p>    <pre>  adb pull <设备里的文件路径> [电脑上的目录]</pre>    <p>其中 <code>电脑上的目录</code> 参数可以省略,默认复制到当前目录。</p>    <p>例:</p>    <pre>  adb pull /sdcard/sr.mp4 ~/tmp/</pre>    <p><em>小技巧:</em>设备上的文件路径可能需要 root 权限才能访问,如果你的设备已经 root 过,可以先使用 <code>adb shell</code> 和 <code>su</code> 命令在 adb shell 里获取 root 权限后,先 <code>cp /path/on/device /sdcard/filename</code> 将文件复制到 sdcard,然后 <code>adb pull /sdcard/filename /path/on/pc</code>。</p>    <h3>复制电脑里的文件到设备</h3>    <p>命令:</p>    <pre>  adb push <电脑上的文件路径> <设备里的目录></pre>    <p>例:</p>    <pre>  adb push ~/sr.mp4 /sdcard/</pre>    <p><em>小技巧:</em>设备上的文件路径普通权限可能无法直接写入,如果你的设备已经 root 过,可以先 <code>adb push /path/on/pc /sdcard/filename</code>,然后 <code>adb shell</code> 和 <code>su</code> 在 adb shell 里获取 root 权限后,<code>cp /sdcard/filename /path/on/device</code>。</p>    <h2>模拟按键/输入</h2>    <p>在 <code>adb shell</code> 里有个很实用的命令叫 <code>input</code>,通过它可以做一些有趣的事情。</p>    <p><code>input</code> 命令的完整 help 信息如下:</p>    <pre>  Usage: input [<source>] <command> [<arg>...]    The sources are:        mouse        keyboard        joystick        touchnavigation        touchpad        trackball        stylus        dpad        gesture        touchscreen        gamepad    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)</pre>    <p>比如使用 <code>adb shell input keyevent <keycode></code> 命令,不同的 keycode 能实现不同的功能,完整的 keycode 列表详见<a href="/misc/goto?guid=4959677439687183377">KeyEvent</a>,摘引部分我觉得有意思的如下:</p>    <table>     <thead>      <tr>       <th>keycode</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>3</td>       <td>HOME 键</td>      </tr>      <tr>       <td>4</td>       <td>返回键</td>      </tr>      <tr>       <td>5</td>       <td>打开拨号应用</td>      </tr>      <tr>       <td>6</td>       <td>挂断电话</td>      </tr>      <tr>       <td>24</td>       <td>增加音量</td>      </tr>      <tr>       <td>25</td>       <td>降低音量</td>      </tr>      <tr>       <td>26</td>       <td>电源键</td>      </tr>      <tr>       <td>27</td>       <td>拍照(需要在相机应用里)</td>      </tr>      <tr>       <td>64</td>       <td>打开浏览器</td>      </tr>      <tr>       <td>82</td>       <td>菜单键</td>      </tr>      <tr>       <td>85</td>       <td>播放/暂停</td>      </tr>      <tr>       <td>86</td>       <td>停止播放</td>      </tr>      <tr>       <td>87</td>       <td>播放下一首</td>      </tr>      <tr>       <td>88</td>       <td>播放上一首</td>      </tr>      <tr>       <td>122</td>       <td>移动光标到行首或列表顶部</td>      </tr>      <tr>       <td>123</td>       <td>移动光标到行末或列表底部</td>      </tr>      <tr>       <td>126</td>       <td>恢复播放</td>      </tr>      <tr>       <td>127</td>       <td>暂停播放</td>      </tr>      <tr>       <td>164</td>       <td>静音</td>      </tr>      <tr>       <td>176</td>       <td>打开系统设置</td>      </tr>      <tr>       <td>187</td>       <td>切换应用</td>      </tr>      <tr>       <td>207</td>       <td>打开联系人</td>      </tr>      <tr>       <td>208</td>       <td>打开日历</td>      </tr>      <tr>       <td>209</td>       <td>打开音乐</td>      </tr>      <tr>       <td>210</td>       <td>打开计算器</td>      </tr>      <tr>       <td>220</td>       <td>降低屏幕亮度</td>      </tr>      <tr>       <td>221</td>       <td>提高屏幕亮度</td>      </tr>      <tr>       <td>223</td>       <td>系统休眠</td>      </tr>      <tr>       <td>224</td>       <td>点亮屏幕</td>      </tr>      <tr>       <td>231</td>       <td>打开语音助手</td>      </tr>      <tr>       <td>276</td>       <td>如果没有 wakelock 则让系统休眠</td>      </tr>     </tbody>    </table>    <p>下面是 <code>input</code> 命令的一些用法举例。</p>    <h3>电源键</h3>    <p>命令:</p>    <pre>  adb shell input keyevent 26</pre>    <p>执行效果相当于按电源键。</p>    <h3>菜单键</h3>    <p>命令:</p>    <pre>  adb shell input keyevent 82</pre>    <h3>HOME 键</h3>    <p>命令:</p>    <pre>  adb shell input keyevent 3</pre>    <h3>返回键</h3>    <p>命令:</p>    <pre>  adb shell input keyevent 4</pre>    <h3>音量控制</h3>    <p>增加音量:</p>    <pre>  adb shell input keyevent 24</pre>    <p>降低音量:</p>    <pre>  adb shell input keyevent 25</pre>    <p>静音:</p>    <pre>  adb shell input keyevent 164</pre>    <h3>媒体控制</h3>    <p>播放/暂停:</p>    <pre>  adb shell input keyevent 85</pre>    <p>停止播放:</p>    <pre>  adb shell input keyevent 86</pre>    <p>播放下一首:</p>    <pre>  adb shell input keyevent 87</pre>    <p>播放上一首:</p>    <pre>  adb shell input keyevent 88</pre>    <p>恢复播放:</p>    <pre>  adb shell input keyevent 126</pre>    <p>暂停播放:</p>    <pre>  adb shell input keyevent 127</pre>    <h3>点亮/熄灭屏幕</h3>    <p>可以通过上文讲述过的模拟电源键来切换点亮和熄灭屏幕,但如果明确地想要点亮或者熄灭屏幕,那可以使用如下方法。</p>    <p>点亮屏幕:</p>    <pre>  adb shell input keyevent 224</pre>    <p>熄灭屏幕:</p>    <pre>  adb shell input keyevent 223</pre>    <h3>滑动解锁</h3>    <p>如果锁屏没有密码,是通过滑动手势解锁,那么可以通过 <code>input swipe</code> 来解锁。</p>    <p>命令(参数以机型 Nexus 5,向上滑动手势解锁举例):</p>    <pre>  adb shell input swipe 300 1000 300 500</pre>    <p>参数 <code>300 1000 300 500</code> 分别表示<code>起始点x坐标 起始点y坐标 结束点x坐标 结束点y坐标</code>。</p>    <h3>输入文本</h3>    <p>在焦点处于某文本框时,可以通过 <code>input</code> 命令来输入文本。</p>    <p>命令:</p>    <pre>  adb shell input text hello</pre>    <p>现在 <code>hello</code> 出现在文本框了。</p>    <h2>查看日志</h2>    <p>Android 系统的日志分为两部分,底层的 Linux 内核日志输出到 /proc/kmsg,Android 的日志输出到 /dev/log。</p>    <h3>Android 日志</h3>    <p>命令格式:</p>    <pre>  [adb] logcat [<option>] ... [<filter-spec>] ...</pre>    <p>常用用法列举如下:</p>    <p>按级别过滤日志</p>    <p>Android 的日志分为如下几个级别:</p>    <ul>     <li>V —— Verbose(最低,输出得最多)</li>     <li>D —— Debug</li>     <li>I —— Info</li>     <li>W —— Warning</li>     <li>E —— Error</li>     <li>F —— Fatal</li>     <li>S —— Silent(最高,啥也不输出)</li>    </ul>    <p>按某级别过滤日志则会将该级别及以上的日志输出。</p>    <p>比如,命令:</p>    <pre>  adb logcat *:W</pre>    <p>会将 Warning、Error、Fatal 和 Silent 日志输出。</p>    <p>按 tag 和级别过滤日志</p>    <p>比如,命令:</p>    <pre>  adb logcat ActivityManager:I MyApp:D *:S</pre>    <p>表示输出 tag <code>ActivityManager</code> 的 Info 以上级别日志,输出 tag <code>MyApp</code> 的 Debug 以上级别日志,及其它 tag 的 Silent 级别日志(即屏蔽其它 tag 日志)。</p>    <p>日志格式</p>    <p>可以用 <code>adb logcat -v <format></code> 选项指定日志输出格式。</p>    <p>日志支持按以下几种 <code><format></code>:</p>    <ul>     <li> <p>brief</p> <p>默认格式。格式为:</p> <pre>  <priority>/<tag>(<pid>): <message></pre> <p>示例:</p> <pre>  D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0</pre> </li>     <li> <p>process</p> <p>格式为:</p> <pre>  <priority>(<pid>) <message></pre> <p>示例:</p> <pre>  D( 1785) Disconnected process message: 10, size: 0  (HeadsetStateMachine)</pre> </li>     <li> <p>tag</p> <p>格式为:</p> <pre>  <priority>/<tag>: <message></pre> <p>示例:</p> <pre>  D/HeadsetStateMachine: Disconnected process message: 10, size: 0</pre> </li>     <li> <p>raw</p> <p>格式为:</p> <pre>  <message></pre> <p>示例:</p> <pre>  Disconnected process message: 10, size: 0</pre> </li>     <li> <p>time</p> <p>格式为:</p> <pre>  <datetime> <priority>/<tag>(<pid>): <message></pre> <p>示例:</p> <pre>  08-28 22:39:39.974 D/HeadsetStateMachine( 1785): Disconnected process message: 10, size: 0</pre> </li>     <li> <p>threadtime</p> <p>格式为:</p> <pre>  <datetime> <pid> <tid> <priority> <tag>: <message></pre> <p>示例:</p> <pre>  08-28 22:39:39.974  1785  1832 D HeadsetStateMachine: Disconnected process message: 10, size: 0</pre> </li>     <li> <p>long</p> <p>格式为:</p> <pre>  [ <datetime> <pid>:<tid> <priority>/<tag> ]  <message></pre> <p>示例:</p> <pre>  [ 08-28 22:39:39.974  1785: 1832 D/HeadsetStateMachine ]  Disconnected process message: 10, size: 0</pre> </li>    </ul>    <p>指定格式可与上面的过滤同时使用。比如:</p>    <pre>  adb logcat -v long ActivityManager:I *:S</pre>    <p>清空日志</p>    <pre>  adb logcat -c</pre>    <h3>内核日志</h3>    <p>命令:</p>    <pre>  adb shell dmesg</pre>    <p>输出示例:</p>    <pre>  <6>[14201.684016] PM: noirq resume of devices complete after 0.982 msecs  <6>[14201.685525] PM: early resume of devices complete after 0.838 msecs  <6>[14201.753642] PM: resume of devices complete after 68.106 msecs  <4>[14201.755954] Restarting tasks ... done.  <6>[14201.771229] PM: suspend exit 2016-08-28 13:31:32.679217193 UTC  <6>[14201.872373] PM: suspend entry 2016-08-28 13:31:32.780363596 UTC  <6>[14201.872498] PM: Syncing filesystems ... done.</pre>    <p>中括号里的 <code>[14201.684016]</code> 代表内核开始启动后的时间,单位为秒。</p>    <p>通过内核日志我们可以做一些事情,比如衡量内核启动时间,在系统启动完毕后的内核日志里找到 <code>Freeing init memory</code> 那一行前面的时间就是。</p>    <h2>查看设备信息</h2>    <h3>型号</h3>    <p>命令:</p>    <pre>  adb shell getprop ro.product.model</pre>    <p>输出示例:</p>    <pre>  Nexus 5</pre>    <h3>电池状况</h3>    <p>命令:</p>    <pre>  adb shell dumpsys battery</pre>    <p>输入示例:</p>    <pre>  Current Battery Service state:    AC powered: false    USB powered: true    Wireless powered: false    status: 2    health: 2    present: true    level: 44    scale: 100    voltage: 3872    temperature: 280    technology: Li-poly</pre>    <p>其中 <code>scale</code> 代表最大电量,<code>level</code> 代表当前电量。上面的输出表示还剩下 44% 的电量。</p>    <h3>屏幕分辨率</h3>    <p>命令:</p>    <pre>  adb shell wm size</pre>    <p>输出示例:</p>    <pre>  Physical size: 1080x1920</pre>    <p>该设备屏幕分辨率为 1080px * 1920px。</p>    <h3>屏幕密度</h3>    <p>命令:</p>    <pre>  adb shell wm density</pre>    <p>输出示例:</p>    <pre>  Physical density: 420</pre>    <p>该设备屏幕密度为 420dpi。</p>    <h3>显示屏参数</h3>    <p>命令:</p>    <pre>  adb shell dumpsys window displays</pre>    <p>输出示例:</p>    <pre>  WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)    Display: mDisplayId=0      init=1080x1920 420dpi cur=1080x1920 app=1080x1794 rng=1080x1017-1810x1731      deferred=false layoutNeeded=false</pre>    <p>其中 <code>mDisplayId</code> 为 显示屏编号,<code>init</code> 是初始分辨率和屏幕密度,<code>app</code> 的高度比 <code>init</code> 里的要小,表示屏幕底部有虚拟按键,高度为 1920 - 1794 = 126px 合 42dp。</p>    <h3>android_id</h3>    <p>命令:</p>    <pre>  adb shell settings get secure android_id</pre>    <p>输出示例:</p>    <pre>  51b6be48bac8c569</pre>    <h3>IMEI</h3>    <p>在 Android 4.4 及以下版本可通过如下命令获取 IMEI:</p>    <pre>  adb shell dumpsys iphonesubinfo</pre>    <p>输出示例:</p>    <pre>  Phone Subscriber Info:    Phone Type = GSM    Device ID = 860955027785041</pre>    <p>其中的 <code>Device ID</code> 就是 IMEI。</p>    <p>而在 Android 5.0 及以上版本里这个命令输出为空,得通过其它方式获取了(需要 root 权限):</p>    <pre>  adb shell  su  service call iphonesubinfo 1</pre>    <p>输出示例:</p>    <pre>  Result: Parcel(    0x00000000: 00000000 0000000f 00360038 00390030 '........8.6.0.9.'    0x00000010: 00350035 00320030 00370037 00350038 '5.5.0.2.7.7.8.5.'    0x00000020: 00340030 00000031                   '0.4.1...        ')</pre>    <p>把里面的有效内容提取出来就是 IMEI 了,比如这里的是 <code>860955027785041</code>。</p>    <p>参考:<a href="/misc/goto?guid=4959677439762497266">adb shell dumpsys iphonesubinfo not working since Android 5.0 Lollipop</a></p>    <h3>Android 系统版本</h3>    <p>命令:</p>    <pre>  adb shell getprop ro.build.version.release</pre>    <p>输出示例:</p>    <pre>  5.0.2</pre>    <h3>Mac 地址</h3>    <p>命令:</p>    <pre>  adb shell cat /sys/class/net/wlan0/address</pre>    <p>输出示例:</p>    <pre>  f8:a9:d0:17:42:4d</pre>    <h3>CPU 信息</h3>    <p>命令:</p>    <pre>  adb shell cat /proc/cpuinfo</pre>    <p>输出示例:</p>    <pre>  Processor       : ARMv7 Processor rev 0 (v7l)  processor       : 0  BogoMIPS        : 38.40    processor       : 1  BogoMIPS        : 38.40    processor       : 2  BogoMIPS        : 38.40    processor       : 3  BogoMIPS        : 38.40    Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt  CPU implementer : 0x51  CPU architecture: 7  CPU variant     : 0x2  CPU part        : 0x06f  CPU revision    : 0    Hardware        : Qualcomm MSM 8974 HAMMERHEAD (Flattened Device Tree)  Revision        : 000b  Serial          : 0000000000000000</pre>    <p>这是 Nexus 5 的 CPU 信息,我们从输出里可以看到使用的硬件是 <code>Qualcomm MSM 8974</code>,processor 的编号是 0 到 3,所以它是四核的,采用的架构是 <code>ARMv7 Processor rev 0 (v71)</code>。</p>    <h3>内存信息</h3>    <p>命令:</p>    <pre>  adb shell cat /proc/meminfo</pre>    <p>输出示例:</p>    <pre>  MemTotal:        1027424 kB  MemFree:          486564 kB  Buffers:           15224 kB  Cached:            72464 kB  SwapCached:        24152 kB  Active:           110572 kB  Inactive:         259060 kB  Active(anon):      79176 kB  Inactive(anon):   207736 kB  Active(file):      31396 kB  Inactive(file):    51324 kB  Unevictable:        3948 kB  Mlocked:               0 kB  HighTotal:        409600 kB  HighFree:         132612 kB  LowTotal:         617824 kB  LowFree:          353952 kB  SwapTotal:        262140 kB  SwapFree:         207572 kB  Dirty:                 0 kB  Writeback:             0 kB  AnonPages:        265324 kB  Mapped:            47072 kB  Shmem:              1020 kB  Slab:              57372 kB  SReclaimable:       7692 kB  SUnreclaim:        49680 kB  KernelStack:        4512 kB  PageTables:         5912 kB  NFS_Unstable:          0 kB  Bounce:                0 kB  WritebackTmp:          0 kB  CommitLimit:      775852 kB  Committed_AS:   13520632 kB  VmallocTotal:     385024 kB  VmallocUsed:       61004 kB  VmallocChunk:     209668 kB</pre>    <p>其中,<code>MemTotal</code> 就是设备的总内存,<code>MemFree</code> 是当前空闲内存。</p>    <h3>更多硬件与系统属性</h3>    <p>设备的更多硬件与系统属性可以通过如下命令查看:</p>    <pre>  adb shell cat /system/build.prop</pre>    <p>这会输出很多信息,包括前面几个小节提到的「型号」和「Android 系统版本」等。</p>    <p>输出里还包括一些其它有用的信息,它们也可通过 <code>adb shell getprop <属性名></code> 命令单独查看,列举一部分属性如下:</p>    <table>     <thead>      <tr>       <th>属性名</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>ro.build.version.sdk</td>       <td>SDK 版本</td>      </tr>      <tr>       <td>ro.build.version.release</td>       <td>Android 系统版本</td>      </tr>      <tr>       <td>ro.build.version.security_patch</td>       <td>Android 安全补丁程序级别</td>      </tr>      <tr>       <td>ro.product.model</td>       <td>型号</td>      </tr>      <tr>       <td>ro.product.brand</td>       <td>品牌</td>      </tr>      <tr>       <td>ro.product.name</td>       <td>设备名</td>      </tr>      <tr>       <td>ro.product.board</td>       <td>处理器型号</td>      </tr>      <tr>       <td>ro.product.cpu.abilist</td>       <td>CPU 支持的 abi 列表</td>      </tr>      <tr>       <td>persist.sys.isUsbOtgEnabled</td>       <td>是否支持 OTG</td>      </tr>      <tr>       <td>dalvik.vm.heapsize</td>       <td>每个应用程序的内存上限</td>      </tr>      <tr>       <td>ro.sf.lcd_density</td>       <td>屏幕密度</td>      </tr>     </tbody>    </table>    <h2>实用功能</h2>    <h3>屏幕截图</h3>    <p>命令:</p>    <pre>  adb shell screencap -p /sdcard/sc.png</pre>    <p>然后将 png 文件导出到电脑:</p>    <pre>  adb pull /sdcard/sc.png</pre>    <p>可以使用 <code>adb shell screencap -h</code> 查看 <code>screencap</code> 命令的帮助信息,下面是两个有意义的参数及含义:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>-p</td>       <td>指定保存文件为 png 格式</td>      </tr>      <tr>       <td>-d display-id</td>       <td>指定截图的显示屏编号(有多显示屏的情况下)</td>      </tr>     </tbody>    </table>    <p>实测如果指定文件名以 <code>.png</code> 结尾时可以省略 -p 参数;否则需要使用 -p 参数。如果不指定文件名,截图文件的内容将直接输出到 stdout。</p>    <h3>录制屏幕</h3>    <p>录制屏幕以 mp4 格式保存到 /sdcard:</p>    <pre>  adb shell screenrecord /sdcard/filename.mp4</pre>    <p>需要停止时按 Ctrl-C,默认录制时间和最长录制时间都是 180 秒。</p>    <p>如果需要导出到电脑:</p>    <pre>  adb pull /sdcard/filename.mp4</pre>    <p>可以使用 <code>adb shell screenrecord --help</code> 查看 <code>screenrecord</code> 命令的帮助信息,下面是常见参数及含义:</p>    <table>     <thead>      <tr>       <th>参数</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>--size WIDTHxHEIGHT</td>       <td>视频的尺寸,比如 <code>1280x720</code>,默认是屏幕分辨率。</td>      </tr>      <tr>       <td>--bit-rate RATE</td>       <td>视频的比特率,默认是 4Mbps。</td>      </tr>      <tr>       <td>--time-limit TIME</td>       <td>录制时长,单位秒。</td>      </tr>      <tr>       <td>--verbose</td>       <td>输出更多信息。</td>      </tr>     </tbody>    </table>    <h3>重新挂载 system 分区为可写</h3>    <p><strong>注:需要 root 权限。</strong></p>    <p>/system 分区默认挂载为只读,但有些操作比如给 Android 系统添加命令、删除自带应用等需要对 /system 进行写操作,所以需要重新挂载它为可读写。</p>    <p>步骤:</p>    <ol>     <li> <p>进入 shell 并切换到 root 用户权限。</p> <p>命令:</p> <pre>  adb shell  su</pre> </li>     <li> <p>查看当前分区挂载情况。</p> <p>命令:</p> <pre>  mount</pre> <p>输出示例:</p> <pre>  rootfs / rootfs ro,relatime 0 0  tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0  devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0  proc /proc proc rw,relatime 0 0  sysfs /sys sysfs rw,seclabel,relatime 0 0  selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0  debugfs /sys/kernel/debug debugfs rw,relatime 0 0  none /var tmpfs rw,seclabel,relatime,mode=770,gid=1000 0 0  none /acct cgroup rw,relatime,cpuacct 0 0  none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0  none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0  tmpfs /mnt/asec tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0  tmpfs /mnt/obb tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0  none /dev/memcg cgroup rw,relatime,memory 0 0  none /dev/cpuctl cgroup rw,relatime,cpu 0 0  none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0  none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0  none /sys/fs/cgroup/freezer cgroup rw,relatime,freezer 0 0  /dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0  /dev/block/platform/msm_sdcc.1/by-name/userdata /data ext4 rw,seclabel,nosuid,nodev,relatime,noauto_da_alloc,data=ordered 0 0  /dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0  /dev/block/platform/msm_sdcc.1/by-name/persist /persist ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0  /dev/block/platform/msm_sdcc.1/by-name/modem /firmware vfat ro,context=u:object_r:firmware_file:s0,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=cp437,iocharset=iso8859-1,shortname=lower,errors=remount-ro 0 0  /dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0  /dev/fuse /mnt/shell/emulated/0 fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0</pre> <p>找到其中我们关注的带 /system 的那一行:</p> <pre>  /dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0</pre> </li>     <li> <p>重新挂载。</p> <p>命令:</p> <pre>  mount -o remount,rw -t yaffs2 /dev/block/platform/msm_sdcc.1/by-name/system /system</pre> <p>这里的 <code>/dev/block/platform/msm_sdcc.1/by-name/system</code> 就是我们从上一步的输出里得到的文件路径。</p> </li>    </ol>    <p>如果输出没有提示错误的话,操作就成功了,可以对 /system 下的文件为所欲为了。</p>    <h3>查看连接过的 WiFi 密码</h3>    <p><strong>注:需要 root 权限。</strong></p>    <p>命令:</p>    <pre>  adb shell  su  cat /data/misc/wifi/*.conf</pre>    <p>输出示例:</p>    <pre>  network={      ssid="TP-LINK_9DFC"      scan_ssid=1      psk="123456789"      key_mgmt=WPA-PSK      group=CCMP TKIP      auth_alg=OPEN      sim_num=1      priority=13893  }    network={      ssid="TP-LINK_F11E"      psk="987654321"      key_mgmt=WPA-PSK      sim_num=1      priority=17293  }</pre>    <p><code>ssid</code> 即为我们在 WLAN 设置里看到的名称,<code>psk</code> 为密码,<code>key_mgmt</code> 为安全加密方式。</p>    <h3>设置系统日期和时间</h3>    <p><strong>注:需要 root 权限。</strong></p>    <p>命令:</p>    <pre>  adb shell  su  date -s 20160823.131500</pre>    <p>表示将系统日期和时间更改为 2016 年 08 月 23 日 13 点 15 分 00 秒。</p>    <h3>重启手机</h3>    <p>命令:</p>    <pre>  adb reboot</pre>    <h3>检测设备是否已 root</h3>    <p>命令:</p>    <pre>  adb shell  su</pre>    <p>此时命令行提示符是 <code>$</code> 则表示没有 root 权限,是 <code>#</code> 则表示已 root。</p>    <h3>使用 Monkey 进行压力测试</h3>    <p>Monkey 可以生成伪随机用户事件来模拟单击、触摸、手势等操作,可以对正在开发中的程序进行随机压力测试。</p>    <p>简单用法:</p>    <pre>  adb shell monkey -p <packagename> -v 500</pre>    <p>表示向 <code><packagename></code> 指定的应用程序发送 500 个伪随机事件。</p>    <p>Monkey 的详细用法参考 <a href="/misc/goto?guid=4959677439852545329">官方文档</a>。</p>    <h3>开启/关闭 WiFi</h3>    <p><strong>注:需要 root 权限。</strong></p>    <p>有时需要控制设备的 WiFi 状态,可以用以下指令完成。</p>    <p>开启 WiFi:</p>    <pre>  adb root  adb shell svc wifi enable</pre>    <p>关闭 WiFi:</p>    <pre>  adb root  adb shell svc wifi disable</pre>    <p>若执行成功,输出为空;若未取得 root 权限执行此命令,将执行失败,输出 <code>Killed</code>。</p>    <h2>刷机相关命令</h2>    <h3>重启到 Recovery 模式</h3>    <p>命令:</p>    <pre>  adb reboot recovery</pre>    <h3>从 Recovery 重启到 Android</h3>    <p>命令:</p>    <pre>  adb reboot</pre>    <h3>重启到 Fastboot 模式</h3>    <p>命令:</p>    <pre>  adb reboot bootloader</pre>    <h3>通过 sideload 更新系统</h3>    <p>如果我们下载了 Android 设备对应的系统更新包到电脑上,那么也可以通过 adb 来完成更新。</p>    <p>以 Recovery 模式下更新为例:</p>    <ol>     <li> <p>重启到 Recovery 模式。</p> <p>命令:</p> <pre>  adb reboot recovery</pre> </li>     <li> <p>在设备的 Recovery 界面上操作进入 <code>Apply update</code>-<code>Apply from ADB</code>。</p> <p>注:不同的 Recovery 菜单可能与此有差异,有的是一级菜单就有 <code>Apply update from ADB</code>。</p> </li>     <li> <p>通过 adb 上传和更新系统。</p> <p>命令:</p> <pre>  adb sideload <path-to-update.zip></pre> </li>    </ol>    <h2>更多 adb shell 命令</h2>    <p>Android 系统是基于 Linux 内核的,所以 Linux 里的很多命令在 Android 里也有相同或类似的实现,在 <code>adb shell</code> 里可以调用。本文档前面的部分内容已经用到了 <code>adb shell</code> 命令。</p>    <h3>查看进程</h3>    <p>命令:</p>    <pre>  adb shell ps</pre>    <p>输出示例:</p>    <pre>  USER     PID   PPID  VSIZE  RSS     WCHAN    PC        NAME  root      1     0     8904   788   ffffffff 00000000 S /init  root      2     0     0      0     ffffffff 00000000 S kthreadd  ...  u0_a71    7779  5926  1538748 48896 ffffffff 00000000 S com.sohu.inputmethod.sogou:classic  u0_a58    7963  5926  1561916 59568 ffffffff 00000000 S org.mazhuang.boottimemeasure  ...  shell     8750  217   10640  740   00000000 b6f28340 R ps</pre>    <p>各列含义:</p>    <table>     <thead>      <tr>       <th>列名</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>USER</td>       <td>所属用户</td>      </tr>      <tr>       <td>PID</td>       <td>进程 ID</td>      </tr>      <tr>       <td>PPID</td>       <td>父进程 ID</td>      </tr>      <tr>       <td>NAME</td>       <td>进程名</td>      </tr>     </tbody>    </table>    <h3>查看实时资源占用情况</h3>    <p>命令:</p>    <pre>  adb shell top</pre>    <p>输出示例:</p>    <pre>  User 0%, System 6%, IOW 0%, IRQ 0%  User 3 + Nice 0 + Sys 21 + Idle 280 + IOW 0 + IRQ 0 + SIRQ 3 = 307      PID PR CPU% S  #THR     VSS     RSS PCY UID      Name   8763  0   3% R     1  10640K   1064K  fg shell    top    131  0   3% S     1      0K      0K  fg root     dhd_dpc   6144  0   0% S   115 1682004K 115916K  fg system   system_server    132  0   0% S     1      0K      0K  fg root     dhd_rxf   1731  0   0% S     6  20288K    788K  fg root     /system/bin/mpdecision    217  0   0% S     6  18008K    356K  fg shell    /sbin/adbd   ...   7779  2   0% S    19 1538748K  48896K  bg u0_a71   com.sohu.inputmethod.sogou:classic   7963  0   0% S    18 1561916K  59568K  fg u0_a58   org.mazhuang.boottimemeasure   ...</pre>    <p>各列含义:</p>    <table>     <thead>      <tr>       <th>列名</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>PID</td>       <td>进程 ID</td>      </tr>      <tr>       <td>PR</td>       <td>优先级</td>      </tr>      <tr>       <td>CPU%</td>       <td>当前瞬间占用 CPU 百分比</td>      </tr>      <tr>       <td>S</td>       <td>进程状态(R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程)</td>      </tr>      <tr>       <td>#THR</td>       <td>线程数</td>      </tr>      <tr>       <td>VSS</td>       <td>Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)</td>      </tr>      <tr>       <td>RSS</td>       <td>Resident Set Size 实际使用物理内存(包含共享库占用的内存)</td>      </tr>      <tr>       <td>PCY</td>       <td>调度策略优先级,SP_BACKGROUND/SPFOREGROUND</td>      </tr>      <tr>       <td>UID</td>       <td>进程所有者的用户 ID</td>      </tr>      <tr>       <td>NAME</td>       <td>进程名</td>      </tr>     </tbody>    </table>    <p><code>top</code> 命令还支持一些命令行参数,详细用法如下:</p>    <pre>  Usage: top [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ]      -m num  最多显示多少个进程      -n num  刷新多少次后退出      -d num  刷新时间间隔(单位秒,默认值 5)      -s col  按某列排序(可用 col 值:cpu, vss, rss, thr)      -t      显示线程信息      -h      显示帮助文档</pre>    <h3>其它</h3>    <p>如下是其它常用命令的简单描述,前文已经专门讲过的命令不再额外说明:</p>    <table>     <thead>      <tr>       <th>命令</th>       <th>功能</th>      </tr>     </thead>     <tbody>      <tr>       <td>cat</td>       <td>显示文件内容</td>      </tr>      <tr>       <td>cd</td>       <td>切换目录</td>      </tr>      <tr>       <td>chmod</td>       <td>改变文件的存取模式/访问权限</td>      </tr>      <tr>       <td>df</td>       <td>查看磁盘空间使用情况</td>      </tr>      <tr>       <td>grep</td>       <td>过滤输出</td>      </tr>      <tr>       <td>kill</td>       <td>杀死指定 PID 的进程</td>      </tr>      <tr>       <td>ls</td>       <td>列举目录内容</td>      </tr>      <tr>       <td>mount</td>       <td>挂载目录的查看和管理</td>      </tr>      <tr>       <td>mv</td>       <td>移动或重命名文件</td>      </tr>      <tr>       <td>ps</td>       <td>查看正在运行的进程</td>      </tr>      <tr>       <td>rm</td>       <td>删除文件</td>      </tr>      <tr>       <td>top</td>       <td>查看进程的资源占用情况</td>      </tr>     </tbody>    </table>    <p> </p>    <p>来自:https://github.com/mzlogin/awesome-adb#%E9%87%8D%E5%90%AF%E5%88%B0-recovery-%E6%A8%A1%E5%BC%8F</p>    <p> </p>