说明:此功能实现是以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_ROOT为Android系统源码根目录
二、创建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