(代码流)制作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

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

Logcat
sfd.png

init.rc中这样定义service才对,之前代码贴错了。:cry:

# service MyDeamon
service MyDeamon /system/bin/MyDeamon
    class core
    user root

谢谢分享