|
(代码流)制作Native服务
发表于 2014-10-21 10:15:48
浏览:9282
|
回复:3
打印
只看该作者
[复制链接]
楼主
制作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
复制代码
|
|