Demo实现要点
-
核心服务通常在特定进程执行(一般为守护进程)
-
需要提供IBinder接口,以便应用程序可以进行跨进程的绑定和调用
-
因为共用,所以必须确保多线程安全
-
加入到ServiceManager进程管理
-
实现JNI, 以便应用程序方便调用
native进程实现(实现平方运算)
SQRService.h
#ifndef ANDROID_MISOO_SQRSERVICE_H
#define ANDROID_MISOO_SQRSERVICE_H
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
#include <binder/IInterface.h>
#include <utils/RefBase.h>
namespace android {
class SQRService : public BBinder
{
public:
static int instantiate();
virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
SQRService();
virtual ~SQRService();
};
} // namespace android
#endif
SQRService.cpp
#include <binder/IServiceManager.h>
#include <cutils/log.h>
#include "SQRService.h"
namespace android {
enum {
SQUARE = IBinder::FIRST_CALL_TRANSACTION,
};
int SQRService::instantiate() {
ALOGE("SQRService instantiate");
int r = defaultServiceManager()->addService(String16("misoo.sqr"), new SQRService());//add service to servicemanager
ALOGE("SQRService r= %d\n", r);
return r;
}
SQRService::SQRService() {
ALOGV("SQRService created");
}
SQRService::~SQRService() {
ALOGV("SQRService destroyed");
}
status_t SQRService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch(code) {
case SQUARE:
{
int num = data.readInt32();
reply->writeInt32(num * num);
ALOGE("onTransact::CREATE_NUM..n=%d\n", num);
return NO_ERROR;
}
break;
default:
ALOGE("onTransact::default\n");
return BBinder::onTransact(code, data, reply, flags);
}
}
} // namespace android
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 <cutils/log.h>
#include "SQRService.h"
using namespace android;
int main(int argc, char** argv) {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
SQRService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
Android.mk—生成native守护进程
#libSQRS01.so
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= SQRService.cpp
LOCAL_SHARED_LIBRARIES:= libutils libbinder liblog
LOCAL_PRELINK_MODULE:= false
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= libSQRS01
include $(BUILD_SHARED_LIBRARY)
# squareserver.bin
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= addserver.cpp
LOCAL_SHARED_LIBRARIES:= libutils libbinder libSQRS01 liblog
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= squareserver
include $(BUILD_EXECUTABLE)
提供通用性API:即IBinder接口
SQR.h
#ifndef ANDROID_MISOO_SQR_H
#define ANDROID_MISOO_SQR_H
namespace android {
class SQR {
private:
const void getSQRService();
public:
SQR();
int execute(int n);
};
}; //namespace
#endif
SQR.cpp
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <cutils/log.h>
#include "SQR.h"
namespace android {
sp<IBinder> m_ib;
SQR::SQR() {
getSQRService();
}
const void SQR::getSQRService() {
sp<IServiceManager> sm = defaultServiceManager();
m_ib = sm->getService(String16("misoo.sqr"));
ALOGE("SQR:getSQRService %p\n", sm.get());
if (m_ib == 0) {
ALOGW("SQRService not published, waiting...");
}
}
int SQR::execute(int n) {
Parcel data, reply;
data.writeInt32(n);
ALOGE("SQR::execute");
m_ib->transact(0, data, &reply); //BpBinder
int num = reply.readInt32();
return num;
}
}
JNI
com_misoo_service_Sqr01.h
-
javac com/misoo/service/Sqr01.java
-
javah -classpath . -jni com.misoo.service.Sqr01
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_misoo_service_Sqr01 */
#ifndef _Included_com_misoo_service_Sqr01
#define _Included_com_misoo_service_Sqr01
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_misoo_service_Sqr01
* Method: execute
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_misoo_service_Sqr01_execute
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
com_misoo_service_Sqr01.cpp
#include "com_misoo_service_Sqr01.h"
#include <cutils/log.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "../../SQRService.h"
#include "../../SQR.h"
using namespace android;
JNIEXPORT jint JNICALL Java_com_misoo_service_Sqr01_execute(JNIEnv *env, jobject thiz, jint x) {
ALOGE("Java_com_misoo_service_Sqr01_execute... X=%d\n", x);
SQR* sqrObj = new SQR();
int num = sqrObj->execute(x);
return num;
}
Sqr01.java
package com.misoo.service;
public class Sqr01 {
static {
System.loadLibrary("libSQRS01_jni");
}
public static native int execute(int x);
}
Android.mk—生成上层Apk使用so库
# libSQRS01_jni.so
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= com_misoo_service_Sqr01.cpp ../../SQR.cpp
LOCAL_SHARED_LIBRARIES:= libutils libbinder liblog libSQRS01
LOCAL_PRELINK_MODULE:= false
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= libSQRS01_jni
include $(BUILD_SHARED_LIBRARY)
添加到android系统编译环境
build/target/product/base.mk
PRODUCT_PACKAGES += \
libSQRS01 \
libSQRS01_jni \
squareserver
system/core/rootdir/init.rc
service squareserver /system/bin/squareserver
class core
user root
group root
critical
seclabel u:r:squareserver:s0