zoukankan      html  css  js  c++  java
  • 11、四大组件之二-Service高级(二)Native Service

    一、Service的分类

    1.1>Android Service

    使用Java编写在JVM中运行的服务

    1.2>Native Service

    使用C/C++完成的服务,一般在系统开始时完成初始化,如MediaService, Audio Service等。

    二、Native Service工作流程分析

    int main(int argc, char** argv) {

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();

    LOGI("ServiceManager: %p", sm.get());

    AudioFlinger::instantiate();

    MediaPlayerService::instantiate();

    CameraService::instantiate();

    AudioPolicyService::instantiate();

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

    }

    2.1、创建ProcessState和DefaultServiceManager

    sp<ProcessState> proc(ProcessState::self());

    sp<IServiceManager> sm = defaultServiceManager();

    ProcessState放置在全局变量gProcess中,每个进程只有一个ProcessState对象,负责打开Binder设备驱动,建立线程池等。而IPCThreadState每个线程有一个,IPCThreadState实例登记在Linux线程程的上下文附属数据中,主要负责Binder数据读取,写入和请求处理框架。IPCThreadSate在构造的时候,获取进程的ProcessSate并记录在自己的成员变量mProcess中,通过mProcess可以获取到Binder的句柄。

     2.2、将服务放进ServiceManager

    AudioFlinger::instantiate();

    ===>>

    defaultServiceManager()->addService(String16("media.audio_flinger"), new AudioFlinger());

     2.3、开始服务循环

    ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

    a读取/写入:talkWithDriver()@IPCThreadState对ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进行包装。

    b请求处理:executeCommand(...)@ IPCThreadState

    c循环结构:joinThreadPool()

    joinThreadPool(){

    While(1){

    talkWithDriver(...)

    ...

    executeCommand(...)

     }

    }

    2.4、透过 IBinder::transact() 函数来与核心服务互传数据。

     

    三、编写自己的Native Service

    (1) 编写DemoNativeService 

     1 int DemoService::instantiate() {
     2               LOGE("DemoService instantiate");
     3               int r = defaultServiceManager()->DemoService(
     4                             String16("alfred.demo"), new DemoService());
     5               LOGE("DemoService r = %d
    ", r);
     6               return r;
     7        }
     8 
     9 
    10 status_t DemoService::onTransact(
    11               uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
    12    switch(code) {
    13       case 0: {
    14                       pid_t pid = data.readInt32();
    15                       int num = data.readInt32();
    16                       num = num + 1000;
    17                       reply->writeInt32(num);
    18                       return NO_ERROR;
    19               } break;
    20       default:
    21               return BBinder::onTransact(code, data, reply, flags);
    22    }
    23 }      

    (2) 编写DemoLoader启动DemoNativeService 

    1 int main(int argc, char** argv)
    2 {
    3 sp<ProcessState> proc(ProcessState::self());
    4 sp<IServiceManager> sm = defaultServiceManager();
    5 LOGI("ServiceManager: %p", sm.get());
    6 DemoService::instantiate();
    7 ProcessState::self()->startThreadPool();
    8 IPCThreadState::self()->joinThreadPool();
    9 }

    (3) 编写mk文件

    (4) 编写Native代码调用DemoNativeService 

     1 int Demo::setN(int n){
     2    getDemoService();
     3    Parcel data, reply;
     4    data.writeInt32(getpid());
     5    data.writeInt32(n);
     6 
     7    LOGE("BpDemoService::create remote()->transact()
    ");
     8    binder->transact(0, data, &reply);
     9    int i = reply.readInt32();
    10    return i;
    11 }
    12 const void Demo::getDemoService(){
    13    sp<IServiceManager> sm = defaultServiceManager();
    14    binder = sm->getService(String16("guilh.add"));
    15    LOGE("Add::getDemoService %p
    ",sm.get());
    16    if (binder == 0) {
    17            LOGW("DemoService not published, waiting...");
    18            return;
    19    }
    20 }

    (5) 使用JNI实现Java和NativeService的衔接

    (6) 在Activity中调用DemoNativeService

     

  • 相关阅读:
    ETL利器Kettle实战应用解析系列三 【ETL后台进程执行配置方式】
    ETL利器Kettle实战应用解析系列二 【应用场景和实战DEMO下载】
    Kettle使用介绍
    java反射详解
    request详解
    java访问接口
    原生JS写Ajax的请求函数-原生ajax
    阿拉伯数字金额转换为大写
    深入理解Java中的String
    Strust2中,加入监听器来判断用户是否在session中存在。
  • 原文地址:https://www.cnblogs.com/androidsj/p/3972511.html
Copyright © 2011-2022 走看看