制作android native service

来源:互联网 发布:牛彩暴雪源码带 编辑:程序博客网 时间:2024/05/29 17:52

android平台上经常谈到三种service

1.四大组件中提到的service,此service属于应用层的service

2.framework层的java service, 例如WindowManagerService, WifiService, PowerManagerService等

3.framework层的native service,例如SurfaceFlinger,MediaPlayerService等


本文主要讲如何写一个framework层的native service, 原理不深入讲。



上图是一个写过的根据系统所处场景(video, camera, music等)调节系统频率电压的服务。

 写一个native service主要分主要分4步:

1.定义接口:

class ICpuFreqService: public IInterface
{
public:
    DECLARE_META_INTERFACE(CpuFreqService);
    static inline sp<ICpuFreqService> connect();
    virtual bool addScence(int) = 0;
    virtual bool leaveScence(int) = 0;

};

2.实现传输层。

client调用BpCpuFreqService,BpCpuFreqService把参数打包成Parcel传到BnCpuFreqService,BnCpuFreqService

解析Parcel得到参数调用CpuFreqService的具体实现,执行完BnCpuFreqService将CpuFreqService的返回值打包成

Parcel再传回BpCpuFreqService,这就是一次跨进程调用

3.实现接口

CpuFreqService得到系统场景信息后会根据配置文件调整驱动相关参数。

4.把服务注册进ServiceManager

首先写个main.c:

int main(int argc, char** argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();

    CpuFreqService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

CpuFreqService::instantiate();的实现如下,就是把服务注册进ServiceManager:

static void instantiate() {
   defaultServiceManager()->addService(
           String16("cpufreqservice"), new CpuFreqService());
}


编译成myservice可执行文件后添加进init.rc,作为开机即启动的服务:

service actionsserver /system/bin/myservice
    user system


client如何调用服务:

sp<ICpuFreqService> cpufreqService = ICpuFreqService::connect();

cpufreqService.addScence(ICpuFreqService::VIDEO);


ICpuFreqService::connect()实现如下:

static inline sp<ICpuFreqService> connect()
    {
        sp<ICpuFreqService> cpufreqService;
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> binder;

    do {
    binder = sm->getService(String16("cpufreqservice"));
    if (binder != 0) {
    break;
    }
    LOGW("cpufreqservice not published, waiting...");
    usleep(500000); // 0.5 s
    } while(true);


    cpufreqService = interface_cast<ICpuFreqService>(binder);
    LOGE_IF(cpufreqService == 0, "no cpufreqService!?");
    return cpufreqService;
    }

获得的ICpuFreqService接口其实是一个BpCpuFreqService对象,

调用过程是BpCpuFreqService------>BnCpuFreqService->CpuFreqService



原创粉丝点击