编写第一个Android Native Service :SQRService,求平方(Square)运算。
为什么有核心服务呢?
1. 核心服务是 Android 框架里最接近Linux/Driver 的部分。为了充分发挥硬件设备的差异化特性,核心服务是让上层Java 应用程序来使用Driver/HW Device 特色的重要管道。
2. 在开机过程中,就可以启动核心服务(例如汉字输入法服务等),让众多应用程序来共享之。
3. 由于共享,所以能有效降低 Java 应用程序的大小(Size)。
看图!
步骤:
I、编写Native Service:SQRService
II、编写SQR.cpp来使用SQRService
III、编写Java层Client来使用核心服务
IV、编写一个Java层ActivityI、
以C++编写一个SQRService,它的功能是将一个数值(例如5)做平方的运算,然后传出其计算结果(5^2 = 5*5 = 25)。
SQRService.h
//SQRService.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();
}
注意:在Java层,Binder类实现了IBinder接口;
在C++层,BBInder类实现了IBinder接口。
SQRService.cpp
//SQRService.cpp
namespace android{
enum{
SQUARE = IBinder::FIRST_CALL_TRANSACTION,
};
int SQRService::instantiate(){
LOGE("SQRService instantiate");
int r = defaultServiceManager()->addService(String16("com.devwang.sqr"),new SQRService());
LOGE("SQRService r = %d \n",r);
return r;
}
SQRService::SQRService(){
LOGV("SQRService created");
}
SQRService::~SQRService(){
LOGV("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);//平方运算
LOGE("onTransact::CREATE_NUM.. num = %d \n",num);
return NO_ERROR;
}
break;
default:
LOGE("onTransact::default\n");
return BBinder::onTransact(code,data,reply,flags);
}
}
}//namespace android
编写一个Make文件:
Android.mk
//Android.mk
LOCAL_MODULE:=libSQRS
执行此Android.mk就可进行编译(Cpmpile)和链接(Link),生成libSQRS.so共享库。
使用C++编写可独立执行的sqrserver.cpp程序。此程序先创建SQRService的对象,然后将它添加到Binder Driver里。
注意:
暂时不改写init.rc文件,以及重新启动设备(以防服务有错导致死机);
先使用sqrserver程序来测试这个核心服务。
//sqrserver.cpp
using namespace android;
int main(int argc, char const *argv[])
{
sp proc(ProcessState::self);
sp sm = defaultServiceManager();
LOGI("ServiceManager:%p",sm.get());
SQRService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
//SQR.h
namespace android{
class SQR
{
private:
const void getSQRService();
public:
SQR();
int execute(int n);
}
}//namespace android
//SQR.cpp
namespace android{
sp m_ib;
SQR:SQR(){
getSQRService();
}
const void SQR::getSQRService(){
sp sm = defaultServiceManager();
m_ib = sm->getService(String16("com.devwang.sqr"));
LOGE("SQR:getSQRService %p\n",sm.get());
if(m_ib == 0){
LOGW("SQRService not published,wating...");
}
return;
}
SQR::execute(int n){
Parcel data,reply;
data.writeInt32(n);
LOGE("SQR::execute\n");
m_ib->transact(0,data,&reply);
int num = reply.readInt32();
return num;
}
}
//com_devwang_service_sqr.cpp
using namespace ansroid;
JNIEXPORT jint JNICALL Java_com_devwang_service_sqr_execute(JNIEnv *env,jobject thiz,jint x){
char s[] = "Java_com_devwang_service_sqr_execute!!!";
LOGE("%s x = %d\n",s,x);
SQR* sqrObj = new SQR();
int num = sqrObj->execute(x);
return num;
}
//sqr.java
package com.devwang.service;
public class sqr{
static{
system.loadLibrary("libSQRS_jni");
}
public static native int execute(int x);
};
IV、
编写一个Java层Activity,如:sqrActivity.java,使用sqr.java中的native函数即OK。
视频教程:参照以下这三个,不得不说高老的视频很赞,得有强硬的基础才能看懂。