ADB介绍与简单入门


ADB(Android Debug Bridge) 是一个用于管理 android 终端(或者模拟器)状态的工具。它的 c-s 工作方式包含有下面主要部分:
客户端 – 客户端运行在 PC 端,通过执行 ADB 命令,可以获得用户资格。其他的 android 工具,例如 ADT , DDMS 等也可以建立 ADB 用户。
服务器端 – 在 PC 端有一个后台程序会运行,这个后台程序主要用于处理客户端与 Android 终端(或者模拟器)之间的通信。
Daemon 服务 – 这是一个运行在 Android 终端(或者模拟器)上的后台程序。
 
ADB 客户端运行后,首先查看是否有运行的 ADB 服务器,如果没有,一个新的 ADB 服务程序会被建立。
* daemon not running. starting it now *
* daemon started successfully *
这个服务程序会绑定 PC 的 TCP-5037 端口,监听从 ADB 客户端发送来的命令。同时,这个服务程序会建立从客户端到Android 终端(或者模拟器)之间的通信。每个 Android 终端(或者模拟器)需要两个相连的端口,偶数端口( 5554-5584 )用于控制台连接,奇数端口 (5555-5585) 用于 ADB 连接。服务程序会扫描从端口 5555 到 5585 的 ADB 连接,查找 ADB daemon 服务,从而建立从 Android 终端到 PC 客户端的连接。这样开发者可以通过输入 ADB 命令管理。
 
下面讲一讲如何在 windows 环境下使用 ADB 。下载 adb.exe ,以及一些附带的驱动, .dll 文件等。
-           开始 -> 运行 ->cmd
-           进入 adb.exe 所在的文件夹,如果 adb.exe 及相关库文件存放于 windows32(或者更新了系统path) ,则忽略这一步
-           Adb devices
-           Adb shell
-           # ls     
 
有的时候,由于多次连接或者不正常退出,ADB会识别出多余的(假的)终端/模拟器,这个时候在输入 > adb devices命令之后会列出一些offline的设备,输入命令,例如adb shell的时候会的这样的返回,error: more than one device and emulator。一个简单的解决方案是,关闭adb服务器,然后重新打开。
- adb kill-server
- adb devices
 
下面的常用的adb命令及其解释,(持续更新中)
# ps      // 列出目前运行中的进程
# dmsge   // 打印出内核启动时的Log
# catlog    // 进入捕捉log状态


adb nodaemon server
这是一条神奇的指令,他将告诉你为啥你启动不了你的adb,这样按照他的指示,你就可以解决你的问题了。



1、adb(Android Debug Bridge) 意为android调试桥。

  是android系统中的一种命令行工具,通过它可以和android设备或模拟器通信。

  ADB是一个C/S架构的应用程序,由三部分组成:

  1)adb client, 运行在PC上(为DDMS,即IDE工作)

  2)adb daemon(守护进程), 运行于Emulator(为与Emulator中的VM交互工作);

  3)adb server(服务进程), 运行在PC(任务管理器上有),管理着adb client和adb daemon的通信。server与client通信的端口是是5037,adb server会与emulator交互的,使用的端口有两个,一个是5554专门用于与Emulator实例的连接,那么数据可以从Emulator转发给IDE控制台了,另一个则是5555,专门与adb daemon连接为后面调试使用。
    PS:Emulator/Device占用两个(一组)端口,一个为偶数的5554,一个奇数的5555。
    如果还开启其他的Emulator,则使用的另一组端口是5556,5557,一直到5585.
    adb server开启时就是通过查找5555-5585之间端口来建立与模拟器的连接的,建立连接后就可以用adb的相关命令了。

  ADB的原理详图解

  

  

  

  

  这下总明白了吧。

2.DDMS

  在Eclipse开发工具中开发时,右上角可打开DDMS面板。Android 开发环境中的针对设备上Dalvik虚拟机调试监控服务。它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标等等服务。DDMS启动后会自动调用ADB服务,从而启动ADB服务,而不用开发者手动去启动ADB工具。  因为当用数据线连接设备到电脑上时,adb就会启动(前提是android设备上得先打开“USB调试”模式)。像各种手机助手类的软件主要也是通过调用adb或者ddms来获取和操作手机上的APP。个人感觉因为涉及的东西比较多,有数据线的问题,硬件接口的问题,还有adb,ddms能否顺利启动的问题,所以会出现有时候adb启动会了,或者总是重启。

 3.问题

  因为当用数据线连接设备到电脑上时,adb就会启动(前提是android设备上得先打开“USB调试”模式)。像各种手机助手类的软件主要也是通过调用adb或者ddms来获取和操作手机上的APP。个人感觉因为涉及的东西比较多,有数据线的问题,硬件接口的问题,还有adb,ddms能否顺利启动的问题,所以会出现有时候adb启动会了,或者总是重启。













命令:
adb forward tcp:6100 tcp:7100 // PC上所有6100端口通信数据将被重定向到手机端7100端口server上

或者
adb forward tcp:6100 local:logd // 
PC上所有6100端口通信数据将被重定向到手机端UNIX类型socket上


通过adb forward我们可以接收手机端server[或者unix域socket]程序发出的所有数据,
并且可以用自己写的小程序向手机端server[或者unix域socket]发送我们自己的数据[luther.gliethttp]
表示在PC的HOST端创建一个server监听6100端口,pc上的其它应用程序,比如:A,可以以client身份和6100端口server建立连接,
之后A发送的所有数据将透明传递到手机端监听7100端口的一个应用程序,比如浏览器程序[luter.gliethttp].
代码流程如下:
1.在pc上执行adb forward tcp:6100 tcp:7100指令,该指令尝试连接5037端口,触发HOST回调函数ss_listener_event_func执行.
2.ss_listener_event_func将为该次连接创建一个local_socket,之后等待该local_socket数据[luther.gliethttp],
3.当local_socket数据,即"host:forward:tcp:6100;tcp:7100",到来之后,将执行local_socket_event_func回调函数,读取数据之后交由smart_socket_enqueue==>handle_host_request
4.handle_host_request==>install_listener("tcp:6100", "tcp:7100", transport);
  创建server监听端口socket_loopback_server(6100, SOCK_STREAM);当有客户端连接该端口是执行listener_event_func回调函数
5.现在pc上我们写了一个自己的小应用程序B,和6100端口的server建立连接,于是HOST上的listener_event_func回调函数执行.

[c-sharp]  view plain copy
  1. static void listener_event_func(int _fd, unsigned ev, void *_l)  
  2. {  
  3.     alistener *l = _l;  
  4.     asocket *s;  
  5.     if(ev & FDE_READ) {  
  6.         struct sockaddr addr;  
  7.         socklen_t alen;  
  8.         int fd;  
  9.         alen = sizeof(addr);  
  10.         fd = adb_socket_accept(_fd, &addr, &alen); // 首先接受该连接  
  11.         if(fd < 0) return;  
  12.         gliethttp_server = create_local_socket(fd); // 为我们的小应用程序建立维护对象gliethttp_server  
  13.         if(gliethttp_server) {  
  14.             gliethttp_server->transport = l->transport;  
  15.             connect_to_remote(gliethttp_server, l->connect_to); // 发送"tcp:7100"到手机端,手机端将建立一个与7100端口server链接的gliethttp_client,作为  
  16.                                                  // 与HOST这里建立的gliethttp_server对象进行数据传输的手机端程序[luther.gliethttp]  
  17.                                                  // 如果成功连接之后,手机端adbd将返回"OKAY",进而gliethttp_server和gliethttp_client将绑定在一起  
  18.                                                  // gliethttp_server发送的数据将通过HOST的daemon直接传递给gliethttp_client  
  19.                                                  // gliethttp_client数据将通过手机的adbd直接发送给HOST的gliethttp_server,然后传递给我们的小程序B[lutehr.gliethttp]  
  20.             return;  
  21.         }  
  22.         adb_close(fd);  
  23.     }  
  24. }  
  25. void connect_to_remote(asocket *s, const char *destination)  
  26. {  
  27.     D("Connect_to_remote call /n");  
  28.     apacket *p = get_apacket();  
  29.     int len = strlen(destination) + 1;  
  30.     if(len > (MAX_PAYLOAD-1)) {  
  31.         fatal("destination oversized");  
  32.     }  
  33.     D("LS(%d): connect('%s')/n", s->id, destination);  
  34.     p->msg.command = A_OPEN; // 打开手机端"tcp:7100"端口  
  35.     p->msg.arg0 = s->id;  
  36.     p->msg.data_length = len;  
  37.     strcpy((char*) p->data, destination);   
  38.     send_packet(p, s->transport);  
  39. }  
 

在手机端
output_thread线程将接收到的数据传递给t->transport_socket句柄,该句柄将调用transport_socket_events==>handle_packet
回调函数进一步处理我们的"tcp:7100"命令.
handle_packet==>
gliethttp_client = create_local_service_socket("tcp:7100");创建维护对象gliethttp_client,
进一步执行socket_loopback_client("7100", SOCK_STREAM);尝试打开手机端的7100端口(这时手机端应该已经打开监听7100端口的server程序)[luther.gliethttp].
之后create_remote_socket(p->msg.arg0, t);表示gliethttp_client从手机端7100端口server上接收到的数据将全部传递给
HOST端的gliethttp_server端口,进而传递给我们的小程序B[luther.gliethttp].


你可能感兴趣的:(android,adb)