Native Service初体验

    众所周知,Android的服务分Native Service和Android Service两种,为什么一上来就整Native Service呢,原因很简单,因为C++比较上手啊,才怪吐舌头,是因为老大让我做个Service与应用的调研啦。

    接下来就是菜鸟的基本路线,在拿到Android的工程后,了解基本编译指令后,就开始在网上搜索,于是找到博文为Android添加底层核心服务,然后依葫芦画瓢,在framework/base目录下添加自己的工作目录xService,并在里面分别建立两个目录,一个是libxService,用于实现xService类,一个是xServer,用于添加服务到Service Manager中。

    我这里只展示下主要代码,xService类instantiate:

int xService::instantiate()
{
    sp<IBinder> binder;
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGD("[xiao] xService instantiate with %p", sm.get());
    // 这里主要把xService这个服务添加到Binder Driver中,服务名为guilh.x
    int r = sm->addService(String16("xService"), new xService());
    ALOGD("[xiao] xService result=%d", r);
    return r;
}
    这里需要注意的是日志的输出,原文中的LOGE、LOGV之类是一概编译不过的,事实上Native层的输出可以使用cutils/log.h中的ALOG系列,即在前加个A。

    然后就是响应调用:

status_t xService::onTransact(uint32_t code, const Parcel& data, Parcel *reply, uint32_t flags)
{
    ALOGD("[xiao] onTrasact()->enter with code: %d", code);
    switch (code) // 根据code的不同执行不同的操作
    {
    case 0:
        {
            pid_t pid = data.readInt32();
            int num = data.readInt32();
            if (8 == num)
            {
                reply->writeInt32(8);
                reply->writeString8(String8("hello world by String8!"));
            }
            else if (16 == num)
            {
                reply->writeInt32(16);
                reply->writeString16(String16("hello world by String16!"));
            }
            else
            {
                reply->writeInt32(num+1000);
            }
            return NO_ERROR;
        }
    default:
        return BBinder::onTransact(code, data, reply, flags);
}
    因为应用层的Parcel类只有readString方法,所以这里我做了个分支确认下实际对应的Native层是哪种String,事实上在我测试中显示是String16类型的。
    另需要注意的有两点:

    1、在写添加服务到Service Manager的应用时,需添加下面这一句,以便让应用生成到system/bin目录下,否则会生成到symbol/system/bin,那么在init.rc中添加因无法找到应用,无法自启动服务。

LOCAL_MODULE_TAGS := eng

    2、如何修改init.rc的问题,如果只是remake工程,可直接修改生成的中间文件mediatek/config/out/[pName]/init.rc或out/target/product/[pName]/root/init.rc,其中[pName]为
实际工程名称,但这种修改会在new后还原,如需在根本上修改,在我这边使用的MTK项目中,则需修改mediatek/config/mt6572/init.rc,不过这个需new才会生效。在init.rc的末尾添加以下这一句:

service xService /system/bin/xServer
    class main

    至于在应用中调用服务接口,如按原文做法:   

 IBinder binder = ServiceManager.getService("xService");// 取得服务
    则只能做为内置应用,如想用像普通应用那样在Eclipse中开发调试,刚需可采用以下方法获取服务:

private IBinder getBinderObj(){
    IBinder binder = null;
    try{
        Method m = Class.forName("android.os.ServiceManager").getMethod("getService", new Class[]{String.class});
        if(m != null){
            Log.d(TAG, "getBinderObj Method:"+m.toString());
        }else{
            Log.d(TAG, "getBinderObj Method null");
        }
        binder = (IBinder)m.invoke(null, new Object[]{"xService"});
        if(binder != null){
            Log.d(TAG, "getBinderObj binder:"+binder.toString());
        }else{
            Log.d(TAG, "getBinderObj binder null");
        }
    }catch(Exception e){
        Log.d(TAG, "getBinderObj exception:"+e.toString());
    }
    return binder;
}
    这样即可很方便的测试服务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值