ADB原理,Wi-Fi连接,常用命令及拓展

jaychee 3年前
   <h3><strong>ADB的原理</strong></h3>    <p>ADB(Android Debug Bridge)是一个通用的命令行工具,能让你和模拟器或连接的Android手机通信。</p>    <p>ADB的结构是一个client-server的结构,包含3个部分:</p>    <ul>     <li> <p>A Client : 发送命令。客户端在你开发的PC上运行,当你在shell里使用Adb命令的时候就会开启一个client。(其实你的shell就是一个client)</p> </li>     <li> <p>A daemon : 在设备上执行命令。守护进程在设备上后台运行。(也就是一个叫做aabd的东西,运行在Andriod设备的底层)</p> </li>     <li> <p>A server : 管理客户端(client)和守护进程(daemon)的连接。server在开发app的PC上后台运行。</p> </li>    </ul>    <p>你可以在 <sdk>/platform-tools 找到adb工具</p>    <h3><strong>ADB是如何工作的?</strong></h3>    <p>当你开启一个adb client,client会首先检查adb server是否运行,如果没有的话先启动一个adb server,当server启动后,server默认绑定到本地(PC)的TCP端口5037(这个端口号可以设置,后文有述)并开始监听从client发送的命令。(所有的adb client都会用5037端口和server通信)</p>    <p>然后server会建立和所有正在运行的设备或模拟器的通信连接。server通过扫描5555至5585之间的奇数号端口查找设备(这就是说设备所使用的端口号一定是5555-5585之间的奇数),如果server找到了一个守护进程daemon(运行在设备上的),那么server就会在这个端口建立一个连接(server是client和daemon的中间的桥梁)</p>    <p>注意:每一个设备需要一对连续的端口号,奇数端口号用来建立adb连接,偶数端口号用于控制台连接(原文是console connections,据我理解应该是指 控制模拟器用的console连接 )</p>    <p>像这样:</p>    <pre>  Emulator 1, console: 5554  Emulator 1, adb: 5555  Emulator 2, console: 5556  Emulator 2, adb: 5557  and so on...</pre>    <p>上一个结构图:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/ec7f60c7db4914388c9923b85cd50a37.jpg"></p>    <p>结构图</p>    <p>有可能有人会问:5555-5585的奇数端口号是指定设备的,那么设备有没有 <strong>上限</strong> 呢?</p>    <p>答案是没有,原因如下:</p>    <p>1.adb可以使用WiFi连接,也就是通过无线网络连接。下文会讲无线连接如何使用</p>    <p>2.adb可以为adb server指定端口号,指定端口号后可以开启多个server(不过Android Studio在调试程序时只识别5037端口的server)。</p>    <p>像这样:</p>    <p>可以通过大写的-P指定端口号,指定端口号后会开启一个新的server,这样的缺点就是,如果以后想查看5038端口server的一系列操作,比如查看连接的设备也必须加 -P 5038,否则查看的只是5037的server连接的设备。</p>    <p>如果之前已经开启了5037的server,那么现在你的PC上现在已经有了两个server,这里注意,你的设备只能和其中一个server通信。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/ee105b8e3ef74aa05a098db45d126c5d.png"></p>    <p>大写的 -P 指定端口号</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/de960f3f9c07003951b1fbe15e3afa88.png"></p>    <p>de960f3f9c07003951b1fbe15e3afa88.png</p>    <p>正式因为上面结构图的结构,才能使得adb能够通过wifi进行连接。</p>    <h3><strong>使用wi-fi连接的使用方法:</strong></h3>    <p>1.将你的Android设备和你的开发机器连接到 <strong>同一个Wi-Fi网络环境</strong> 下,记住是 <strong>同一个</strong> 。不是 <strong>所有</strong> 的无线节点都可以 <strong>匹配</strong> ,你也许需要使用支持adb的防火墙配置。(我将防火墙关闭了)</p>    <p>2.将你的设备和电脑通过USB连接</p>    <p>3.将你的手机设置成在端口5555监听TCP/ip连接(在PC上执行,端口号自己指定)</p>    <p>$ adb tcpip 5555</p>    <p>4.断开USB数据线</p>    <p>5.查看你的手机的IP地址(在手机连接的WiFi网络的心里了能看到,每个手机的配置不一样~)</p>    <p>6.通过指定IP地址进行连接</p>    <p>$ adb connect <device-ip-address></p>    <p>7.看看效果吧,确定你的电脑是否已经连接上你的手机了</p>    <pre>  $ adb devices  List of devices attached  <device-ip-address>:5555 device</pre>    <p>如果没有连接上</p>    <ul>     <li> <p>确定连在同一个wifi环境下</p> </li>     <li> <p>重试 adb connect 或重启adb server adb kill-server & adb start-server</p> </li>    </ul>    <p>熟悉Android Studio的人应该知道有一个叫做 ADBWIFI 的调试插件,里面用到的也是这些命令原理,刚开始我还觉得能自己开发一款Android Studio的插件很神奇,其实你打开那个链接琢磨琢磨,你也可以。里面用到了ddmlib这个jar包,文章的最后 <strong>简要</strong> 介绍一下(感兴趣的话可以好好研究。。)</p>    <h3><strong>ADB常用命令</strong></h3>    <p>语法: adb [-d|-e|-s <serialNumber>] <command></p>    <p>如果你只连接一个物理设备,可以通过-d快速指定物理设备,如果你连接了只连接了一个模拟器,可以通过-e快速指定模拟器。</p>    <ul>     <li>devices : 连接的设备列表,你可以看到serialNumber</li>     <li>help : 命令帮助</li>     <li>version : adb版本</li>     <li>logcat [option] [filter-specs] :在屏幕上打印log,如果这个命令不会可以输入 adb logcat --help 查看怎么使用</li>     <li>bugreport : 打印dumpsys, dumpstate, logcat的信息,为了报告bug,类似 adb bugreport > xxx.log</li>     <li>start-server : 开启一个adb server</li>     <li>kill-server : 关闭adb server</li>     <li>install <path-to-apk> :安装apk(specified as a full path to an .apk file))</li>     <li>pull <remote> <local> : 从你设备的remote拷贝文件到你PC上的local</li>     <li>push <local> <remote> : 从你PC上的local拷贝文件到你设备的remote</li>     <li>forward <local> <remote> : 将你本地的特定端口的信息转发给你设备的remote端口上。<br> like this: <p>adb forward tcp:6100 tcp:7100 PC上所有6100端口通信数据将被重定向到手机端7100端口server上</p> <p>adb forward tcp:6100 local:logd PC上所有6100端口通信数据将被重定向到手机端UNIX类型socket上</p> </li>     <li>get-serialno : 得到设备的序列号,其实就是devices的结果的前半部分</li>     <li>get-state : 得到设备的状态[offline, device, no device]</li>     <li>wait-for-device : 直到设备online之后才会继续执行,否则阻塞执行。like this: <p>adb wait-for-device install <app>.apk 安装apk需要设备启动之后才能执行,和其他adb命令配合使用</p> </li>    </ul>    <p>jdwp 和 ppp两个命令没搞清楚如何使用,欢迎知道的告诉我,互相学习,感谢 :)</p>    <h3><strong>adb shell</strong></h3>    <p>shell命令 运行在android的设备上,命令的二进制文件在手机的 /system/bin/... 下</p>    <p>语法: adb [-d|-e|-s <serialNumber>] shell <shell_command></p>    <p>am</p>    <p>在shell命令下,你可以通过activity manager 工具(am)执行系统操作,包括开始一个activity, 强制关闭进程,广播intent,设置设备屏幕参数等。</p>    <p>语法是 am <command> ,eg : adb shell am start -a android.intent.action.VIEW</p>    <p>内容比较多,建议KX上网详细看,原文挺简单的,我就不翻译了 :)</p>    <p>和am搭配使用的有:</p>    <table>     <thead>      <tr>       <th>Comand</th>       <th>Description</th>      </tr>     </thead>     <tbody>      <tr>       <td>start [options] <INTENT></td>       <td>Start an <a href="/misc/goto?guid=4959551246929042449" rel="nofollow,noindex">Activity</a> specified by <a href="/misc/goto?guid=4959721726126363173" rel="nofollow,noindex"><INTENT></a></td>      </tr>      <tr>       <td>startservice [options] <INTENT></td>       <td>Start the <a href="/misc/goto?guid=4959715941465275336" rel="nofollow,noindex">Service</a> specified by <INTENT>.</td>      </tr>      <tr>       <td>force-stop <PACKAGE></td>       <td>Force stop everything associated with <PACKAGE> (the app's package name).</td>      </tr>      <tr>       <td>kill [options] <PACKAGE></td>       <td>Kill all processes associated with <PACKAGE> (the app's package name). This command kills only processes that are safe to kill and that will not impact the user experience.</td>      </tr>     </tbody>    </table>    <p>pm</p>    <p>在shell命令下,你可以通过package manager(pm)执行和包相关的操作。语法是 pm <command> ,eg : adb shell pm uninstall com.example.MyApp ,和am类似,这里就不一一展开了。</p>    <p>截图</p>    <p>像这样eg: $ adb shell screencap /sdcard/screen.png</p>    <p>你还可以这样,截屏后从手机copy一份。</p>    <pre>  $ adb shell  shell@ $ screencap /sdcard/screen.png  shell@ $ exit  $ adb pull /sdcard/screen.png</pre>    <p>录屏</p>    <p>仅支持 Android 4.4 (API level 19)及以上</p>    <p>Note:Audio is not recorded with the video file.</p>    <p>仅仅是画面而已</p>    <p>还有很多参数可以设置,这里不展开</p>    <p>eg: $ adb shell screenrecord /sdcard/demo.mp4</p>    <p><strong>其他</strong></p>    <p>dumpsys</p>    <pre>  dumpsys [options]           meminfo 显示内存信息           cpuinfo 显示CPU信息           account 显示accounts信息           activity 显示所有的activities的信息           window 显示键盘,窗口和它们的关系           wifi 显示wifi信息           and so on</pre>    <p>eg: adb shell dumpsys meminfo [packageName]</p>    <p>By the way....你可以在 <strong>java代码中执行这些命令</strong> ,并将结果写到文件中,然后将文件发送到你的服务器上进行分析~~</p>    <p>参考:</p>    <p><a href="/misc/goto?guid=4959721726256011737" rel="nofollow,noindex">Running Shell commands though java code on Android?</a></p>    <p><a href="/misc/goto?guid=4959721726341973604" rel="nofollow,noindex">writing dumpstate to file android</a></p>    <h3><strong>ADB扩展</strong></h3>    <p>这里只简单的说一些。</p>    <p>ADBWIFI 插件的源码下载下来后你可以看到里面有一个ddmlib的类库,它的位置在你的android-sdk下面的/sdk/tools/lib 目录下,这个目录下还有ddmuilib.jar,ddms.jar等。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/52463105e63b60970431a4018c01daab.png"></p>    <p style="text-align: center;">52463105e63b60970431a4018c01daab.png</p>    <p>那么这些工具有什么用呢?</p>    <p>通过这些工具你可以在你的代码中</p>    <p>1.创建ADB</p>    <pre>  AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();</pre>    <p>2.获得ADB连接的设备</p>    <pre>  IDevice devices[] = bridge.getDevices();</pre>    <p>3.操作设备</p>    <pre>  device.installPackage(path, true, args);  //device instance of IDevice  device.uninstallPackage(pakagename);</pre>    <p>4.执行adb命令</p>    <pre>  device.executeShellCommand(cmd, receiver);  // receiver extends MultiLineReceiver  // cmd like "dumpsys meminfo [packageName]" adb shell command</pre>    <p>是不是很酷?如果能够再深入下去应该能发掘更多有意思的东西,感兴趣的自己研究研究吧,东西挺多的 :)</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/f82b733bd6ac</p>    <p> </p>