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




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