bunchen 发表于 2014-10-21 10:15:48

(代码流)制作Native服务

制作Native服务很简单,主要有两个步骤:1.创建服务。2.把服务加入到Android系统的ServiceManager。
一、首先,创建服务。创建Natvie服务,我们可以新建一个集成自BBinder的类。BBinder类是一个抽象类,是android进程间通信的工具,我们要实现这个方法来实现我们的功能:
virtual status_t onTransact(uint32_t , const Parcel& , Parcel* , uint32_t);
因此,我们创建一个Nativie服务叫MyService
#ifndef __MYSERVICE_H__
#define __MYSERVICE_H__

#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>

namespace android
{
        class MyService : public BBinder
        {
        public :
                static int Instance();
                MyService();
                virtual ~MyService();
                virtual status_t onTransact(uint32_t , const Parcel& , Parcel* , uint32_t);
        };
}

#endif
实现MyService的功能:
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "MyService.h"


#define DEBUG 1

#if DEBUG
#define LOG_TAG "MyService"
#endif

#include <utils/Log.h>
#include <stdio.h>
#include <stdlib.h>
       
namespace android
{
        static pthread_key_t sigbuskey;
        int MyService::Instance()
        {       
                if(DEBUG) ALOGD("MyService Instantiate\n");
                int ret = defaultServiceManager()->addService(String16("tchip.MyService"),new MyService());
               
                if(DEBUG) ALOGD("MyService ret = %d\n",ret);
               
                return ret ;
        }
       
        MyService::MyService()
        {
                if(DEBUG) ALOGD("MyService create\n");
                pthread_key_create(&sigbuskey,NULL);
               
        }
        MyService::~MyService()
        {
                pthread_key_delete(sigbuskey);
                if(DEBUG) ALOGD("MyService destory\n");
        }
        status_t MyService::onTransact(uint32_t code , const Parcel & data,Parcel * reply,uint32_t flags)
        {
                if(DEBUG) ALOGD("transact for %u\n",code);
                switch(code)
                {
                case 0 :
                        {
                                reply->writeCString("Greeting from MyService .");
                                return NO_ERROR ;
                        }
                default :
                        return BBinder::onTransact(code,data,reply,flags);
                }
        }
}
这里能看到如何消息code是0是我们返回一个"Greeting from MyService ."字符串。

二、然后,我们把MyService加入到Android系统的ServiceManager。这个工作在MyDeamon程序中调用MyService::Instance()来完成,并加入到线程池中成为守护精灵。
#include "MyService.h"
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

using namespace android;

int main(int argc , char ** argv)
{
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        int ret = MyService::Instance();
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
}
可以看到在MyService::Instance()中的int ret = defaultServiceManager()->addService(String16("tchip.MyService"),new MyService());这一句就是核心。

三、最后,我们在写一个测试程序,从MyService中返回数据。
#include <stdio.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

using namespace android;

sp<IBinder> binder ;

int main(){
        sp<IServiceManager> sm = defaultServiceManager();
        binder = sm->getService(String16("tchip.MyService"));
        if(binder == 0)
        {
                printf("MyService not published !\n");
                return -1 ;
        }
        Parcel data , reply ;
        binder->transact(0,data,&reply);
        const char * msg = reply.readCString();
        printf("msg : %s\n",msg);
        return 0 ;
}
我们再写一个Android.mk文件来编译:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := MyDeamon

LOCAL_SRC_FILES := \
        MyService.cpp \
        MyDeamon.cpp \
       
LOCAL_SHARED_LIBRARIES := libutils libbinder liblog
LOCAL_MODULE_TAGS := $(TARGET_BUILD_VARIANT)

include $(BUILD_EXECUTABLE)

######################
# only for test
######################
include $(CLEAR_VARS)

LOCAL_MODULE := MyTest

LOCAL_SRC_FILES := \
        MyTest.cpp \
       
LOCAL_SHARED_LIBRARIES := libutils libbinder
LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

编译完后把可执行文件push到设备的/system/bin下运行:
先运行MyDeamon,打开服务。
接着在另一个终端运行MyTest


最后的最后,如果我们把这个Native服务放到init.rc中赋予root权限,这样这个服务就可以做更多事情了:
# service MyDeamon
/system/bin/MyDeamon
    class core
    user root

bunchen 发表于 2014-10-21 10:19:27

第一次发帖不知怎样贴图片现在补会运行后的效果图。:(
运行MyTest的结过


Logcat


bunchen 发表于 2014-10-21 10:35:26

init.rc中这样定义service才对,之前代码贴错了。:'(
# service MyDeamon
service MyDeamon /system/bin/MyDeamon
    class core
    user root

xiaofei 发表于 2016-7-8 16:27:25


谢谢分享
页: [1]
查看完整版本: (代码流)制作Native服务