(代码流)制作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
第一次发帖不知怎样贴图片现在补会运行后的效果图。:(
运行MyTest的结过
Logcat
init.rc中这样定义service才对,之前代码贴错了。:'(
# service MyDeamon
service MyDeamon /system/bin/MyDeamon
class core
user root
谢谢分享
页:
[1]