提前声明:此文章为学习后的一些心得体会,若有错误请指出,如有侵权请联系。
Binder驱动不是单独拿出来分析,是结合在Android中的使用情景分析的,我们在此是结合Android Service来分析Binder驱动:
主要分析以下几部分:
1.服务的注册过程;
2.服务的获取和使用过程;
3.transaction stack机制(replay和双向服务)。
在Android系统中,Binder的使用是很常见的,无论是java层、C++层还是C层使用Binder系统都是通过底层的Binder驱动。
Binder的作用就是为了提供进程间通信的一种方法,Android中的service类似于网络通信中C/S模式,Binder的作用与http/UDP作用类似,只是提供的数据的通道;
网络通讯中只要应用层序解析数据包的协议一致,我们就可以在不同的平台(windows、linux、mac)之间通信;
Android中的service也一样,只要上层服务和客户端解析数据的协议一致,则C层、C++层和Java层都可以通过Binder进行通信。
我们在此分析由易到难,先分析C层的,然后分析C++和Java层的。
先贴出C层分析的代码:
可以参考 framework/native/cmds/servicemanager目录下的代码编写测试程序,在此我贴出简化版的的示例,仅用于分析;
一共有6个文件:
binder.c binder.h service_manager.c test_client.c test_server.c test_server.h
其中前3个文件可以在Android系统源码中找到。
1 #ifndef _TEST_SERVER_H 2 #define _TEST_SERVER_H 3 4 #define HELLO_SVR_CMD_SAYHELLO 1 5 #define HELLO_SVR_CMD_SAYHELLO_TO 2 6 7 #endif // _TEST_SERVER_H
1 int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr) 2 { 3 int status; 4 unsigned iodata[512/4]; 5 struct binder_io msg, reply; 6 7 bio_init(&msg, iodata, sizeof(iodata), 4); 8 bio_put_uint32(&msg, 0); // strict mode header 9 bio_put_string16_x(&msg, SVC_MGR_NAME); 10 bio_put_string16_x(&msg, name); 11 bio_put_obj(&msg, ptr); 12 13 if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE)) 14 return -1; 15 16 status = bio_get_uint32(&reply); 17 18 binder_done(bs, &msg, &reply); 19 20 return status; 21 } 22 23 void sayhello(void) 24 { 25 static int cnt = 0; 26 fprintf(stderr, "say hello : %d ", ++cnt); 27 } 28 29 30 int sayhello_to(char *name) 31 { 32 static int cnt = 0; 33 fprintf(stderr, "say hello to %s : %d ", name, ++cnt); 34 return cnt; 35 } 36 37 int hello_service_handler(struct binder_state *bs, 38 struct binder_transaction_data *txn, 39 struct binder_io *msg, 40 struct binder_io *reply) 41 { 42 uint16_t *s; 43 char name[512]; 44 size_t len; 45 uint32_t handle; 46 uint32_t strict_policy; 47 int i; 48 49 strict_policy = bio_get_uint32(msg); 50 51 switch(txn->code) { 52 case HELLO_SVR_CMD_SAYHELLO: 53 sayhello(); 54 bio_put_uint32(reply, 0); 55 return 0; 56 57 case HELLO_SVR_CMD_SAYHELLO_TO: 58 s = bio_get_string16(msg, &len); //"IHelloService" 59 s = bio_get_string16(msg, &len); // name 60 if (s == NULL) { 61 return -1; 62 } 63 for (i = 0; i < len; i++) 64 name[i] = s[i]; 65 name[i] = '