Android service命令介绍

之前在使用adb时,用过很多命令 比如adb install 等最后是调用了 pm相关命令,和java service相关的命令都在Framework/base/cmds目录下,今天我们来讲下service命令,这个命令可以和任何一个注册到servicemanager的service进行通信。代码在Framework/native/cmds/service下。


一、命令

我们先看下help介绍:

Usage: service [-h|-?]
       service list
       service check SERVICE
       service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR ] ...
Options:
   i32: Write the 32-bit integer N into the send parcel.
   i64: Write the 64-bit integer N into the send parcel.
   f:   Write the 32-bit single-precision number N into the send parcel.
   d:   Write the 64-bit double-precision number N into the send parcel.
   s16: Write the UTF-16 string STR into the send parcel.

service list列出所有的service,call service就是向相关service传递命令,各个参数的类型可以用i32等表示。


例子:

比如命令

service call phone 2 s16 "123"

就是调用了下面函数 s16代表String类型 "123"就是参数。

void call(String number);


二、源码

我们来看下service的源码:

int main(int argc, char* const argv[])
{
    sp<IServiceManager> sm = defaultServiceManager();//获取servicemanager的binder
    fflush(stdout);
    if (sm == NULL) {
        aerr << "service: Unable to get default service manager!" << endl;
        return 20;
    }
    
    bool wantsUsage = false;
    int result = 0;
    
    while (1) {
        int ic = getopt(argc, argv, "h?");
        if (ic < 0)
            break;

        switch (ic) {
        case 'h':
        case '?':
            wantsUsage = true;
            break;
        default:
            aerr << "service: Unknown option -" << ic << endl;
            wantsUsage = true;
            result = 10;
            break;
        }
    }
    
    if (optind >= argc) {
        wantsUsage = true;
    } else if (!wantsUsage) {
        if (strcmp(argv[optind], "check") == 0) {//check命令
            optind++;
            if (optind < argc) {
                sp<IBinder> service = sm->checkService(String16(argv[optind]));
                aout << "Service " << argv[optind] <<
                    (service == NULL ? ": not found" : ": found") << endl;
            } else {
                aerr << "service: No service specified for check" << endl;
                wantsUsage = true;
                result = 10;
            }
        }
        else if (strcmp(argv[optind], "list") == 0) {//list命令
            Vector<String16> services = sm->listServices();
            aout << "Found " << services.size() << " services:" << endl;
            for (unsigned i = 0; i < services.size(); i++) {
                String16 name = services[i];
                sp<IBinder> service = sm->checkService(name);
                aout << i 
                     << "\t" << good_old_string(name) 
                     << ": [" << good_old_string(get_interface_name(service)) << "]"
                     << endl;
            }
        } else if (strcmp(argv[optind], "call") == 0) {//call命令
            optind++;
            if (optind+1 < argc) {
                int serviceArg = optind;
                sp<IBinder> service = sm->checkService(String16(argv[optind++]));//获取service的binder
                String16 ifName = get_interface_name(service);
                int32_t code = atoi(argv[optind++]);
                if (service != NULL && ifName.size() > 0) {//下面把数据分装在Parcel中
                    Parcel data, reply;

                    // the interface name is first
                    data.writeInterfaceToken(ifName);

                    // then the rest of the call arguments
                    while (optind < argc) {
                        if (strcmp(argv[optind], "i32") == 0) {
                            optind++;
                            if (optind >= argc) {
                                aerr << "service: no integer supplied for 'i32'" << endl;
                                wantsUsage = true;
                                result = 10;
                                break;
                            }
                            data.writeInt32(atoi(argv[optind++]));
                        } else if (strcmp(argv[optind], "i64") == 0) {
                            optind++;
                            if (optind >= argc) {
                                aerr << "service: no integer supplied for 'i64'" << endl;
                                wantsUsage = true;
                                result = 10;
                                break;
                            }
                            data.writeInt64(atoll(argv[optind++]));
                        } else if (strcmp(argv[optind], "s16") == 0) {
                            optind++;
                            if (optind >= argc) {
                                aerr << "service: no string supplied for 's16'" << endl;
                                wantsUsage = true;
                                result = 10;
                                break;
                            }
                            data.writeString16(String16(argv[optind++]));
                        } else if (strcmp(argv[optind], "f") == 0) {
                            optind++;
                            if (optind >= argc) {
                                aerr << "service: no number supplied for 'f'" << endl;
                                wantsUsage = true;
                                result = 10;
                                break;
                            }
                            data.writeFloat(atof(argv[optind++]));
                        } else if (strcmp(argv[optind], "d") == 0) {
                            optind++;
                            if (optind >= argc) {
                                aerr << "service: no number supplied for 'd'" << endl;
                                wantsUsage = true;
                                result = 10;
                                break;
                            }
                            data.writeDouble(atof(argv[optind++]));
                        } else if (strcmp(argv[optind], "null") == 0) {
                            optind++;
                            data.writeStrongBinder(NULL);
                        } else if (strcmp(argv[optind], "intent") == 0) {
                        	
                        	char* action = NULL;
                        	char* dataArg = NULL;
                        	char* type = NULL;
                        	int launchFlags = 0;
                        	char* component = NULL;
                        	int categoryCount = 0;
                        	char* categories[16];
                        	
                        	char* context1 = NULL;
                        	
                            optind++;
                            
                        	while (optind < argc)
                        	{
                        		char* key = strtok_r(argv[optind], "=", &context1);
                        		char* value = strtok_r(NULL, "=", &context1);
                                
                                // we have reached the end of the XXX=XXX args.
                                if (key == NULL) break;
                        		
                        		if (strcmp(key, "action") == 0)
                        		{
                        			action = value;
                        		}
                        		else if (strcmp(key, "data") == 0)
                        		{
                        			dataArg = value;
                        		}
                        		else if (strcmp(key, "type") == 0)
                        		{
                        			type = value;
                        		}
                        		else if (strcmp(key, "launchFlags") == 0)
                        		{
                        			launchFlags = atoi(value);
                        		}
                        		else if (strcmp(key, "component") == 0)
                        		{
                        			component = value;
                        		}
                        		else if (strcmp(key, "categories") == 0)
                        		{
                        			char* context2 = NULL;
                        			int categoryCount = 0;
                        			categories[categoryCount] = strtok_r(value, ",", &context2);
                        			
                        			while (categories[categoryCount] != NULL)
                        			{
                        				categoryCount++;
                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
                        			}
                        		}
                                
                                optind++;
                        	} 
                        	
                            writeString16(data, action);
                            writeString16(data, dataArg);
                            writeString16(data, type);
                       		data.writeInt32(launchFlags);
                            writeString16(data, component);
                        	
                            if (categoryCount > 0)
                            {
                                data.writeInt32(categoryCount);
                                for (int i = 0 ; i < categoryCount ; i++)
                                {
                                    writeString16(data, categories[i]);
                                }
                            }
                            else
                            {
                                data.writeInt32(0);
                            }                            
  
                            // for now just set the extra field to be null.
                       		data.writeInt32(-1);
                        } else {
                            aerr << "service: unknown option " << argv[optind] << endl;
                            wantsUsage = true;
                            result = 10;
                            break;
                        }
                    }
                    
                    service->transact(code, data, &reply);//调用binder的transact函数,像相关service传递数据
                    aout << "Result: " << reply << endl;
                } else {
                    aerr << "service: Service " << argv[serviceArg]
                        << " does not exist" << endl;
                    result = 10;
                }
            } else {
                if (optind < argc) {
                    aerr << "service: No service specified for call" << endl;
                } else {
                    aerr << "service: No code specified for call" << endl;
                }
                wantsUsage = true;
                result = 10;
            }
        } else {
            aerr << "service: Unknown command " << argv[optind] << endl;
            wantsUsage = true;
            result = 10;
        }
    }


有了service call这个命令非常实用,比如我们自己写个service,也可以使用这个命令,来调试各个binder接口。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值