Android Native Service简单实现示例

说明:此功能实现是以Android系统源码作为基础的。

原著作者及链接:

①作者:longfeey

链接:http://blog.csdn.net/longfeey/article/details/5887026

②作者blackboycpp

链接:http://blog.csdn.net/blackboyofsnp/article/details/7243070

 

此文用作笔记,以备学习和查阅。

一、Android系统源码的根目录下的/development目录下创建自己的目录。

$(ANDROID_ROOT)/development/myModule

注:ANDROID_ROOTAndroid系统源码根目录

 

二、创建libaddservice目录

$(ANDROID_ROOT)/development/libaddservice

此目录下存放的文件有:

AddService.cpp

AddService.h

Android.mk

 

AddService.h源码实现如下:

#ifndef ANDROID_ADD_SERVICE_H
#define ANDROID_ADD_SERVICE_H

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

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

#endif


AddService.cpp源码实现如下:

#include <stdio.h>
#include "AddService.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

namespace android
{
	static pthread_key_t sigbuskey;

	int AddService::instance()
	{
		printf("AddService instantiate\n");
//添加服务到binder
		int r = defaultServiceManager()->addService(String16("service.add"), new AddService());
		printf("AddService r = %d\n", r);

        return r; 
	}

	AddService::AddService()
	{
        pthread_key_create(&sigbuskey, NULL);
    }

	AddService::~AddService()
    {
		pthread_key_delete(sigbuskey);
    }

	status_t AddService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
	{
		switch(code)
		{
        case 0: 
		{
			printf("onTransact case 0\n");
			pid_t pid = data.readInt32();
			int num = data.readInt32();
			num += 1000;
			printf("case 0 num=%d\n", num);
			reply->writeInt32(num);
			return NO_ERROR;
		}
		break;
		default:
			return BBinder::onTransact(code, data, reply, flags);

		}
	} 
}


Android.mk源码实现,如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= AddService.cpp
LOCAL_SHARED_LIBRARIES:= libutils libbinder
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= libAddService
LOCAL_PRELINK_MODULE:= false
include $(BUILD_SHARED_LIBRARY)


三、创建addserver目录

此模块功能是调用libaddservice中的instance,注册自定义service

$(ANDROID_ROOT)/development/addserver

 

此目录下存放的文件有:

addserver.cpp

Android.mk


addserver.cpp源码实现,如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "../libaddservice/AddService.h"

using namespace android;

int main(int argc, char* argv[])
{
	printf("addserver begin\n");
	sp<ProcessState> proc(ProcessState::self());
	sp<IServiceManager> sm = defaultServiceManager();
	printf("ServiceManager: %p\n", sm.get());

	int ret = AddService::instance();
	printf("AddService instantiate return ret=%d\n", ret);

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

	return 0;
}

Android.mk源码实现,如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= addserver.cpp
LOCAL_SHARED_LIBRARIES:= libutils libbinder libAddService
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= addserver
include $(BUILD_EXECUTABLE)

至此为止,可将libaddservice编译成libaddservice.so;将addserver编译成addserver(可执行文件)。执行addserver可注册自定义service

注:编译方法在最后说明。

 

四、创建libaddclient目录。此模块将调用之前注册的service

$(ANDROID_ROOT)/development/libaddclient

此目录下包含的文件:

Add.cpp

Add.h

Android.mk

Add.h源码实现,如下:

#ifndef ANDROID_ADD_H
#define ANDROID_ADD_H

namespace android
{
	class Add
	{
	public:
		int setN(int n);
	private:
		static const void getAddService();
	};
}

#endif

Add.cpp源码实现,如下:

#include <stdio.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include "Add.h"

namespace android
{
	sp<IBinder> binder;
	int Add::setN(int n)
	{
		printf("setN n=%d\n", n);
		getAddService();
		Parcel data, reply;
		data.writeInt32(getpid());
		data.writeInt32(n);
		binder->transact(0, data, &reply);
		int i = reply.readInt32();
		
		printf("Add::setN return i=%d\n", i);
		return i;
	}

	const void Add::getAddService()
	{
		sp<IServiceManager> sm = defaultServiceManager();
		binder = sm->getService(String16("service.add"));
		printf("Add::getAddService %p\n", sm.get());
		if (binder == NULL)
		{
			printf("binder == 0\n");
			return;
		}
	}
};

Android.mk源码实现,如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= Add.cpp
LOCAL_SHARED_LIBRARIES := libutils libbinder
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE := libAdd
LOCAL_PRELINK_MODULE:= false
include $(BUILD_SHARED_LIBRARY)

此模块编译,生成libAdd.so

五、创建test目录。此模块功能为测试程序,调用libAdd.so提供的接口,访问自定义的service

$(ANDROID_ROOT)/development/test

此目录下包含的文件有:

test.cpp

Android.mk

 

test.cpp源码实现,如下:

#include <stdio.h>
#include "../libaddclient/Add.h"

using namespace android;

int main(int argc, char* argv[])
{
	Add objAdd;
	int ret = objAdd.setN(2015);
	printf("test setN return=%d\n", ret);

	return 0;
}

Android.mk源码实现,如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= test.cpp
LOCAL_SHARED_LIBRARIES := libAdd
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE := testExe
include $(BUILD_EXECUTABLE)

至此,所有源码实现已完成。

目录结构如下:



六、编译

进入android源码主目录,运行source build/envsetup.sh 或 . build/envsetup.sh 

然后进入$(ANDROID_ROOT)/development/myModule的各个子目录。在各个子目录下,执行命令:mm

编译顺序,如下:

 

$(ANDROID_ROOT)/development/libaddservice

$(ANDROID_ROOT)/development/addserver

$(ANDROID_ROOT)/development/libaddclient

$(ANDROID_ROOT)/development/test

 

七、在模拟器中测试:

①运行模拟器,此处版本为Android4.4.2-API19

②将so和可执行文件放入模拟器:

adb push libAddService.so /system/lib

adb push libAdd.so /system/lib

adb push addserver /data

adb push testExe /data

③放入模拟器后,先打开一个terminal运行addserver


打开另一个terminal,运行testExe,结果如下:


源码地址:

http://download.csdn.net/detail/mxiaomi/8426797




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章