說明:此功能實現是以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