android usb adb流程[转]

摘要:
前提是需要对usbadb的命令包格式很熟悉。其输出的log信息将被重定向到/data/adb/目录下的文件中。具体源代码,请查看:/system/core/adb/adb.c,system/core/adb/adb.h方法三:由于方法二有一定的局限性,他是将printf的输出重定向到/data/adb/xxxx.txt文件中,这样很多的后台服务的打印信息是打印不出来的。方法如下:[cpp]viewplaincopy/*youmustdefineTRACE_TAGbeforeusingthismacro*/defineD(...)do{if{intsave_errno=errno;adb_mutex_lock;__android_log_print;errno=save_errno;__android_log_print;fflush;adb_mutex_unlock;errno=save_errno;}}while上面的__android_log_print函数需要依赖头文件#include和动态库:liblog,动态库的链接方法:LOCAL_STATIC_LIBRARIES+=liblog#交叉编译时使用LOCAL_LDLIBS+=-llog#编译主机端的adb时使用为了查看更多地log,可以将persist.adb.trace_mask设置为0x3ff。
android adb 概述
android adb的代码分为两部分:
kernel层的代码在如下路径:
drivers/usb/gadget/f_adb.c
drivers/usb/gadget/android.c
他吐给上层应用的是如下的设备节点:/dev/android_adb
应用层的代码在如下路径:
system/core/adb目录
针对device,该目录编译的输出是adbd
控制台上手动启动平板adb的功能的方法如下:
step1:在init.rc中申明adbd服务
  1. <spanstyle="font-size:18px;">serviceadbd/sbin/adbd
  2. classcore
  3. #socketadbdstream660systemsystem
  4. disabled
  5. #seclabelu:r:adbd:s0</span>
step2:init.rc中通过属性变量来触发usb adb功能
  1. onproperty:sys.usb.config=adb
  2. write/sys/class/android_usb/android0/enable0
  3. write/sys/class/android_usb/android0/idVendor18d1
  4. write/sys/class/android_usb/android0/idProductD002
  5. write/sys/class/android_usb/android0/functions${sys.usb.config}
  6. write/sys/class/android_usb/android0/enable1
  7. startadbd
  8. setpropsys.usb.state${sys.usb.config}
step3: init.rc中disable adb
  1. <spanstyle="font-size:18px;">onproperty:sys.usb.config=none
  2. stopadbd
  3. write/sys/class/android_usb/android0/enable0
  4. write/sys/class/android_usb/android0/bDeviceClass0
  5. setpropsys.usb.state${sys.usb.config}</span>
step4:在控制台上执行命令setprop sys.usb.config adb 将使能adb功能
在控制台上执行命令setprop sys.usb.confignone 将关闭adb功能
以上默认是通过usb来实现adb的功能,其实也可以通过网络来实现adb的功能;方法如下:
device端:
step1: setpropservice.adb.tcp.port 5555
step2: setprop sys.usb.confignone
setprop sys.usb.config adb
step3: 通过执行netstat -tna命令确认5555端口被监听。#以上操作如下图
android usb adb流程[转]第7张
pc端:
step1: adb kill-server
step2: adb connect 10.1.32.4 #这里的地址就是平板的地址
step3: adb devices
step3: adb shell #以上操作如下图
android usb adb流程[转]第8张
adb 出问题时的调试方法:
方法一:通过bus hound工具来抓pc跟device之间的usb 包的通讯。前提是需要对usb adb的命令包格式很熟悉。
方法二:由属性变量:persist.adb.trace_mask来控制adb的log输出级别。其输出的log信息将被重定向到/data/adb/目录下的文件中。
具体源代码,请查看:/system/core/adb/adb.c(start_device_log函数), system/core/adb/adb.h(adb_trace_mask,AdbTrace)
方法三:由于方法二有一定的局限性,他是将printf的输出重定向到/data/adb/xxxx.txt文件中,这样很多的后台服务的打印信息是打印不出来的。
因为他的输入,输出被重定向到pty/pts或是pipe或是socket pair上了。所以我们的方法就是修改/system/core/adb/adb.h文件中的# define D(...) 宏,使其的打印输出到logcat中。方法如下:
  1. /*youmustdefineTRACE_TAGbeforeusingthismacro*/
  2. defineD(...)
  3. do{
  4. if(ADB_TRACING){
  5. intsave_errno=errno;
  6. adb_mutex_lock(&D_lock);
  7. __android_log_print(3,"adb","%s::%s():",
  8. __FILE__,__FUNCTION__);
  9. errno=save_errno;
  10. __android_log_print(3,"adb",__VA_ARGS__);
  11. fflush(stderr);
  12. adb_mutex_unlock(&D_lock);
  13. errno=save_errno;
  14. }
  15. }while(0)
上面的__android_log_print函数需要依赖头文件#include <android/log.h>和动态库:liblog ,动态库的链接方法:
LOCAL_STATIC_LIBRARIES += liblog #交叉编译时使用
LOCAL_LDLIBS += -llog#编译主机端的adb时使用
为了查看更多地log,可以将persist.adb.trace_mask设置为0x3ff。

一下将从几个专题来研究devices端的adbd后台的工作内容:

专题一:#######adb 从pc端发送命令到device端的流程:#############
output_thread(system/core/adb/transport.c)
get_apacket(分配一个apacket包所需的内存)
t->read_from_remote(p, t)
write_packet(t->fd, t->serial, &p) //注意该函数,真正只是发送包的开始地址,并不是发送整个包的内容数据
|
|t->fd对应的pipe另一端为: t->transport_socket ,而该句柄的接收处理函数为: transport_socket_events
|
|/
transport_socket_events
read_packet(fd, t->serial, &p)) //fd即为t->transport_socket
handle_packet(p, (atransport *) _t); //该函数根据从pc端发送过来的命令,做相应的处理的。

注意:
read_from_remote/write_to_remote 对应从/dev/android_adb读取和写入数据
专题二:###############adb 从device端发送响应到pc端的流程:#########
send_packet(apacket *p, atransport *t)//函数用来向pc端发送数据(通过usb或以太网)
write_packet(t->transport_socket, t->serial, &p)
|
|t->fd对应的pipe另一端为: t->transport_socket ,该socket对是在 transport_registration_func 函数中申明 |的。
|/
input_thread
read_packet(t->fd, t->serial, &p)
t->write_to_remote(p, t);
|
|
|对应于usb而言
|/
remote_write //发送命令和数据到pc端
usb_write(t->usb, &p->msg, sizeof(amessage)) // 发送命令
usb_write(t->usb, &p->data, size) //发送数据
专题三:pc跟device之间传输adb数据包的格式
他们之间的数据传输单元称为:struct apacket,具体结构如下:
  1. <spanstyle="font-size:18px;">structapacket
  2. {
  3. apacket*next;//adbpackage队列,可以对还未来得及处理的adb数据包进行入队列
  4. unsignedlen;
  5. unsignedchar*ptr;
  6. amessagemsg;//adb数据包对应的命令头,对应一个IN或OUT传输
  7. unsignedchardata[MAX_PAYLOAD];//命令包对应的数据部分,对应一个IN或OUT传输
  8. };</span>
一个 apacket 包传输分为两个阶段:
第一个阶段是:命令传输阶段(required),存储在 apacket.msg 中
第二个阶段是:数据传输阶段(optional),存储在 apacket.data 中
adb支持的命令如下:
  1. <spanstyle="font-size:18px;">#defineA_SYNC0x434e5953//该命令用于adbpush/pull命令
  2. #defineA_CNXN0x4e584e43//该命令用于pc和device进行adb连接时使用,该命令带有数据阶段
  3. #defineA_OPEN0x4e45504f//用于在devices端开启一个服务,譬如adbshell,adblogcat,adbremount等shell命令
  4. #defineA_OKAY0x59414b4f//表示接收ok,该命令没有数据阶段
  5. #defineA_CLSE0x45534c43//关闭对应的连接,关闭和打开都是双向的。
  6. #defineA_WRTE0x45545257//该命令用来向pc端或是device端发送数据,该命令一般都有数据阶段
  7. #defineA_AUTH0x48545541</span>
主题四:device端对收到的pc端来的命令或数据的处理函数:handle_packet
  1. <spanstyle="font-size:18px;">voidhandle_packet(apacket*p,atransport*t)//system/core/adb/adb.c
  2. {
  3. asocket*s;
  4. D("handle_packet()%c%c%c%c ",((char*)(&(p->msg.command)))[0],
  5. ((char*)(&(p->msg.command)))[1],
  6. ((char*)(&(p->msg.command)))[2],
  7. ((char*)(&(p->msg.command)))[3]);
  8. print_packet("recv",p);
  9. switch(p->msg.command){
  10. caseA_SYNC://在adbpush和pull命令时使用。
  11. if(p->msg.arg0){
  12. send_packet(p,t);
  13. if(HOST)send_connect(t);
  14. }else{
  15. t->connection_state=CS_OFFLINE;
  16. handle_offline(t);
  17. send_packet(p,t);
  18. }
  19. return;
  20. caseA_CNXN:/*CONNECT(version,maxdata,"system-id-string")*///在adb连接过程时使用。
  21. /*XXXverifyversion,etc*///首先由pc发送一个A_CNXN命令和对应的数据,然后device收到后,会回复一个
  22. //A_CNXN命令并带上数据阶段。
  23. if(t->connection_state!=CS_OFFLINE){
  24. t->connection_state=CS_OFFLINE;
  25. handle_offline(t);
  26. }
  27. parse_banner((char*)p->data,t);
  28. if(HOST||!auth_enabled){
  29. handle_online(t);
  30. if(!HOST)send_connect(t);
  31. }else{
  32. send_auth_request(t);
  33. }
  34. break;
  35. caseA_AUTH:
  36. if(p->msg.arg0==ADB_AUTH_TOKEN){
  37. t->connection_state=CS_UNAUTHORIZED;
  38. t->key=adb_auth_nextkey(t->key);
  39. if(t->key){
  40. send_auth_response(p->data,p->msg.data_length,t);
  41. }else{
  42. /*Nomoreprivatekeystotry,sendthepublickey*/
  43. send_auth_publickey(t);
  44. }
  45. }elseif(p->msg.arg0==ADB_AUTH_SIGNATURE){
  46. if(adb_auth_verify(t->token,p->data,p->msg.data_length)){
  47. adb_auth_verified(t);
  48. t->failed_auth_attempts=0;
  49. }else{
  50. if(t->failed_auth_attempts++>10)
  51. adb_sleep_ms(1000);
  52. send_auth_request(t);
  53. }
  54. }elseif(p->msg.arg0==ADB_AUTH_RSAPUBLICKEY){
  55. adb_auth_confirm_key(p->data,p->msg.data_length,t);
  56. }
  57. break;
  58. caseA_OPEN:/*OPEN(local-id,0,"destination")*/执行一个adb命令时,首先是发送的这个命令
  59. if(t->online){
  60. char*name=(char*)p->data;//命令对应的数据,该数据字段一般包含所要执行的shell命令
  61. name[p->msg.data_length>0?p->msg.data_length-1:0]=0;
  62. D("openusb ");
  63. s=create_local_service_socket(name);//根据命令的名字执行相应的后台服务线程,通过socket对或是pty/pts来实现本地socket跟
  64. if(s==0){//后台服务线程之间的通讯,本地socket用于跟对应命令的后台服务线程通讯
  65. send_close(0,p->msg.arg0,t);
  66. }else{
  67. s->peer=create_remote_socket(p->msg.arg0,t);//对端socket即用于实现跟pc端的交互,主要是向pc发送数据
  68. s->peer->peer=s;
  69. send_ready(s->id,s->peer->id,t);
  70. s->ready(s);
  71. }
  72. }
  73. break;
  74. caseA_OKAY:/*READY(local-id,remote-id,"")*/
  75. if(t->online){
  76. if((s=find_local_socket(p->msg.arg1))){
  77. if(s->peer==0){
  78. s->peer=create_remote_socket(p->msg.arg0,t);
  79. s->peer->peer=s;
  80. }
  81. s->ready(s);
  82. }
  83. }
  84. break;
  85. caseA_CLSE:/*CLOSE(local-id,remote-id,"")*/
  86. if(t->online){
  87. if((s=find_local_socket(p->msg.arg1))){
  88. s->close(s);//关闭时双向的,现实pc端发送关闭命令,然后是device端回复关闭命令,close对应local_socket_close
  89. }
  90. }
  91. break;
  92. caseA_WRTE://对应pc端给device发送数据,分为两个阶段:一个阶段是命令:WRTE(包含在apacket.msg中);另一个阶段是数据(包含在apacket.data中)
  93. if(t->online){
  94. if((s=find_local_socket(p->msg.arg1))){
  95. unsignedrid=p->msg.arg0;
  96. p->len=p->msg.data_length;
  97. if(s->enqueue(s,p)==0){//enqueue对应的函数是local_socket_enqueue
  98. D("Enqueuethesocket ");
  99. send_ready(s->id,rid,t);
  100. }
  101. return;
  102. }
  103. }
  104. break;
  105. default:
  106. printf("handle_packet:whatis%08x?! ",p->msg.command);
  107. }
  108. put_apacket(p);
  109. }</span>
上面函数中的remote_socket_enqueue函数,用于向pc端发送命令和数据
  1. <spanstyle="font-size:18px;">staticintremote_socket_enqueue(asocket*s,apacket*p)
  2. {
  3. D("enteredremote_socket_enqueueRS(%d)WRITEfd=%dpeer.fd=%d ",
  4. s->id,s->fd,s->peer->fd);
  5. p->msg.command=A_WRTE;//apackge包对应的命令
  6. p->msg.arg0=s->peer->id;
  7. p->msg.arg1=s->id;
  8. p->msg.data_length=p->len;
  9. send_packet(p,s->transport);
  10. return1;
  11. }</span>
上面函数create_local_service_socket的实现如下:
  1. <spanstyle="font-size:18px;">asocket*create_local_service_socket(constchar*name)
  2. {
  3. asocket*s;
  4. intfd;
  5. #if!ADB_HOST
  6. if(!strcmp(name,"jdwp")){
  7. returncreate_jdwp_service_socket();
  8. }
  9. if(!strcmp(name,"track-jdwp")){
  10. returncreate_jdwp_tracker_service_socket();
  11. }
  12. #endif
  13. D("beginservice_to_fd:%s ",name);
  14. fd=service_to_fd(name);//该函数的功能就是根据name来创建相应的后台服务,并创建一个socketpair或是pty/pts管道对,返回的fd对应该管道的一端;
  15. if(fd<0)return0;//该管道的另一端,将dup重定向到该后台服务的输入输出句柄。
  16. s=create_local_socket(fd);//安装本地句柄,即上面返回的fd句柄的输入和输出处理函数:local_socket_event_func
  17. D("LS(%d):boundto'%s'via%d ",s->id,name,fd);
  18. #if!ADB_HOST
  19. if((!strncmp(name,"root:",5)&&getuid()!=0)
  20. ||!strncmp(name,"usb:",4)
  21. ||!strncmp(name,"tcpip:",6)){
  22. D("LS(%d):enablingexit_on_close ",s->id);
  23. s->exit_on_close=1;
  24. }
  25. #endif
  26. returns;
  27. }</span>
local_socket_event_func函数展开如下:该函数是handle_packet与对应的后台服务之间的一个中转函数,他的任务包括:
任务一:将pc端发送过来的命令和数据报(统称为adb package)通过local_socket_enqueue函数放置在struct

apacket的next队列上,并触发如下函数的FDE_WRITE分支的处理,该分支将从apacket队列上取package,并将它写到管道另一端的后台服务上,作为后台服务的输入。

任务二:在要读出后台服务的输出结果时,通过调用函数local_socket_ready来触发如下函数的FDE_READ

分支,该分支将通过管道,读取后台服务的输出数据,并调用s->peer->enqueue(即remote_socket_enqueue函数)将后台服务的输出发送到远端,即pc端上。

  1. <spanstyle="font-size:18px;">staticvoidlocal_socket_event_func(intfd,unsignedev,void*_s)
  2. {
  3. asocket*s=_s;
  4. D("LS(%d):event_func(fd=%d(==%d),ev=%04x) ",s->id,s->fd,fd,ev);
  5. /*puttheFDE_WRITEprocessingbeforetheFDE_READ
  6. **inordertosimplifythecode.
  7. */
  8. if(ev&FDE_WRITE){
  9. apacket*p;
  10. while((p=s->pkt_first)!=0){
  11. while(p->len>0){
  12. intr=adb_write(fd,p->ptr,p->len);//将pc段发送来的命令和数据写到后台服务
  13. if(r>0){
  14. p->ptr+=r;
  15. p->len-=r;
  16. continue;
  17. }
  18. if(r<0){
  19. /*returninghereisokbecauseFDE_READwill
  20. **beprocessedinthenextiterationloop
  21. */
  22. if(errno==EAGAIN)return;
  23. if(errno==EINTR)continue;
  24. }
  25. D("closingafterwritebecauser=%danderrnois%d ",r,errno);
  26. s->close(s);
  27. return;
  28. }
  29. if(p->len==0){
  30. s->pkt_first=p->next;//取队列中的下一个apackage包
  31. if(s->pkt_first==0)s->pkt_last=0;
  32. put_apacket(p);
  33. }
  34. }
  35. /*ifwesentthelastpacketofaclosingsocket,
  36. **wecannowdestroyit.
  37. */
  38. if(s->closing){
  39. D("closingbecause'closing'issetafterwrite ");
  40. s->close(s);
  41. return;
  42. }
  43. /*nomorepacketsqueued,sowecanignore
  44. **writableeventsagainandtellourpeer
  45. **toresumewriting
  46. */
  47. fdevent_del(&s->fde,FDE_WRITE);
  48. s->peer->ready(s->peer);
  49. }
  50. if(ev&FDE_READ){
  51. apacket*p=get_apacket();
  52. unsignedchar*x=p->data;
  53. size_tavail=MAX_PAYLOAD;
  54. intr;
  55. intis_eof=0;
  56. while(avail>0){
  57. r=adb_read(fd,x,avail);//读取后台服务的输出
  58. D("LS(%d):postadb_read(fd=%d,...)r=%d(errno=%d)avail=%d ",s->id,s->fd,r,r<0?errno:0,avail);
  59. if(r>0){
  60. avail-=r;
  61. x+=r;
  62. continue;
  63. }
  64. if(r<0){
  65. if(errno==EAGAIN)break;
  66. if(errno==EINTR)continue;
  67. }
  68. /*r=0orunhandlederror*/
  69. is_eof=1;
  70. break;
  71. }
  72. D("LS(%d):fd=%dpostavailloop.r=%dis_eof=%dforced_eof=%d ",
  73. s->id,s->fd,r,is_eof,s->fde.force_eof);
  74. if((avail==MAX_PAYLOAD)||(s->peer==0)){
  75. put_apacket(p);
  76. }else{
  77. p->len=MAX_PAYLOAD-avail;
  78. <spanstyle="white-space:pre"></span>//以下将后台服务的输出发送到远端pc上。
  79. r=s->peer->enqueue(s->peer,p);//remote_socket_enqueue,该分支在handle_packet函数中的被create_remote_socket初始化
  80. D("LS(%d):fd=%dpostpeer->enqueue().r=%d ",s->id,s->fd,r);
  81. if(r<0){
  82. /*errorreturnmeanstheyclosedusasaside-effect
  83. **andwemustreturnimmediately.
  84. **
  85. **notethatifwestillhavebufferedpackets,the
  86. **socketwillbeplacedontheclosingsocketlist.
  87. **thishandlerfunctionwillbecalledagain
  88. **toprocessFDE_WRITEevents.
  89. */
  90. return;
  91. }
  92. if(r>0){
  93. /*iftheremotecannotacceptfurtherevents,
  94. **wedisablenotificationofREADs.They'll
  95. **beenabledagainwhenwegetacalltoready()
  96. */
  97. fdevent_del(&s->fde,FDE_READ);
  98. }
  99. }
  100. /*Don'tallowaforcedeofifdataisstillthere*/
  101. if((s->fde.force_eof&&!r)||is_eof){
  102. D("closingbecauseis_eof=%dr=%ds->fde.force_eof=%d ",is_eof,r,s->fde.force_eof);
  103. s->close(s);
  104. }
  105. }
  106. if(ev&FDE_ERROR){
  107. /*thisshouldbecaughtbethenextreadorwrite
  108. **catchingitheremeanswemayskipthelastfew
  109. **bytesofreadabledata.
  110. */
  111. //s->close(s);
  112. D("LS(%d):FDE_ERROR(fd=%d) ",s->id,s->fd);
  113. return;
  114. }
  115. }</span>

注意:
system/core/adb/services.c对应各种命令的后台服务
system/core/adb/commandline.c包含各种后台服务的具体实现。
主题五:usb adb的bus hound分析
情景1:adb的链接过程
android usb adb流程[转]第23张
2.1.0
3.1.0
4.1.0
5.1.0
以上是通用的枚举过程,即取得描述符的内容。
6.1.0 set_config
7.1.0 取得描述符
至此完成设备的枚举,开始adb的连接过程。
8.1.0 发送adb命令:A_CNXN 为out传输
9.1.0 发送adb命令A_CNXN所带的数据 为out传输
10.1.0 由device端发送adb命令A_CNXN到host pc段。IN传输
11.1.0 为adb命令A_CNXN所带的数据,IN传输
12.1.0为adb命令A_OPEN
13.1.0为adb命令A_OPEN所带的数据
14.1.0为以上命令的响应:A_OKAY
15.1.0为adb命令A_WRTE
16.1.0为adb命令A_WRTE所带的数据
17.1.0为以上命令的响应
21.1.0位adb命令A_CLSE,没有数据阶段 IN传输
22.1.0为adb命令A_CLSE,没有数据阶段,关闭时双向的。OUT传输
以上即为adb连接过程的usb封包的分析

情景2:adb logcat过程
android usb adb流程[转]第24张

1.1.0对应adb命令A_OPEN
2.1.0对应adb命令A_OPEN所带的数据,这个数据中有如下命令:exec logcat
3.1.0为以上命令的响应,IN传输
4.1.0对应adb命令A_WRTE
5.1.0对应adb命令A_WRTE的数据 IN传输,打开设备节点/dev/log/main
6.1.0为以上命令的响应 OUT传输
7.1.0对应adb命令A_WRTE
8.1.0对应adb命令A_WRTE的数据,即为logcat的输出内容 IN传输
10.1.0为以上命令的响应,OUT传输
再往下,即为上面命令的重复,以不断输出logcat的log信息
情景3:adb pull过程
android usb adb流程[转]第25张
1.1.0对应adb命令A_OPEN
2.1.0对应adb命令A_OPEN所带的数据,这个数据中有如下命令:sync,
该sync命令在service_to_fd函数中,被file_sync_service函数所处理
3.1.0为以上命令的响应,IN传输
4.1.0对应adb命令A_WRTE
5.1.0对应adb命令A_WRTE的数据 IN传输,数据内容为:STAT,pc用该命令来查询该文件是否存在,已经是有权限
6.1.0为以上命令的响应 OUT传输
13.1.0 对应adb命令A_WRTE OUT传输
14.1.0 对应adb命令A_WRTE的数据,该数据包含一个命令:RECV,表示pc从device段接收文件
15.1.0 为以上命令的响应
16.1.0 对应adb命令A_WRTE OUT传输
17.1.0 对应adb命令A_WRTE的数据,表示要pull的是哪个文件
18.1.0 为以上命令的响应
19.1.0 对应adb命令A_WRTE IN传输
20.1.0 对应adb命令A_WRTE的数据:DATA,表示开始数据传输,并且指定下一个命令需要传输的数据大小
21.1.0 为以上命令的响应
22.1.0 对应adb命令A_WRTE IN传输
23.1.0 对应adb命令A_WRTE的数据: 包含文件的具体内容,长度就是上面命令指定的长度
24.1.0 为以上命令的响应
重复19到24这个过程,直到文件被传输完成。
情景4:adb push过程
android usb adb流程[转]第26张
2.1.0对应adb命令A_OPEN所带的数据,这个数据中有如下命令:shell:
3.1.0为以上命令的响应,IN传输
4.1.0对应adb命令A_WRTE IN传输
5.1.0对应adb命令A_WRTE的数据 ,数据内容为:#,即为显示在pc上的cmd窗口上的#号。
6.1.0为以上命令的响应 OUT传输

免责声明:文章转载自《android usb adb流程[转]》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WPF如何获得ListView内各单元格控件STM32-ETH-Lwip以太网通信下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

四、使用ADB命令清除缓存

一、ADB Shell 应用 查看目录结构 :adb shell ls 查看系统当前日期 :adb shell date 查看系统 CPU 使用情况 :adb shell cat /proc/cpuinfo 查看系统内存使用情况 :adb shell cat /proc/meminfo 显示所有应用 :adb shell pm list pack...

UNIX网络编程——网络IPC:套接字

Contents 套接字接口 套接字描述符 寻址 字节序 地址格式 地址查询 绑定地址 建立连接 数据传输 套接字选项 带外数据 UNIX域套接字 使用套接字的示例 面向连接的ruptime 无连接的ruptime 套接字接口       套接字接口是一组用来结合UNIX I/O函数进行进程间通信的函数,大多数系统上都实现了它,包括各...

Android开发记录

http://coffeelover.iteye.com/blog/1039470 一、Android模拟器相关 1. Android模拟器安装 Market 模拟器默认没有安装 Market,看到网上有较为复杂的安装方法,也有1个简单的,试了简单的,在 Android2.2 模拟器下试过是OK的,简单的方法如下:1) 下载2个文件:GoogleServ...

常用adb命令总结

前言 很早就想整理一下自己平时常用的一些adb命令,不仅为了便于以后查找,而且整理的过程自己又重新复习了一遍,但是当我开始在度娘一搜的时候,发现很多人已经写的非常详细了,尤其是当我发现了这篇adb概括 心中一句NND,怎么可以写的这么详细,瞬间没了想写这篇文章的欲望,如果你点了链接发现确实很全,那么恭喜你可以关掉这篇了,哈哈哈。 我就不这么想的,虽然很全,...

3--Java NIO基础1

一、NIO概述 1. BIO带来的挑战 BIO即堵塞式I/O,数据在写入或读取时都有可能堵塞,一旦有堵塞,线程将失去CPU的使用权,性能较差。 2. NIO工作机制 Java NIO由Channel、Buffer、Selector三个核心组成,NIO框架类结构图如下: 其中,Buffer主要负责存取数据,Channel用于数据传输,获取数据,然后流入Bu...

usb

USB Host的意思是该设备可以作为USB主机连接USB外围设备,如连接U盘、键盘、鼠标等。 与之对等的是USB Device(有些地方翻译成target),意思是该设备可以以U盘的身份连接USB主机。 对于手机来说,同时支持Host和Device模式的,称之为OTG USB linux 设备通常有一个或多个配置; 配置通常有一个或多个接口; 接口通常有...