android的service大概有这么几种情势,Java service ,native service,或Java层通过某种通讯方式比如socket和demon交互.
Java层的aidl很方便,写socket的demon方式也很好理解,native的就显得略微麻烦1点,我们通过1个例子来讲1下,首先说我们不讲授binder的内部机制….
我们打算写个简单的service,只提供set和get方法
1. 先写1个bin 的可履行文件
int main(int argc, char** argv)
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
sm->addService(String16("service.test"),new Test ());
IPCThreadState::self()->joinThreadPool();
}
sp<IServiceManager> sm = defaultServiceManager();
我们实际得到了servicemanager的binder proxy,通过这个接口我们可以调用servicemanager的方法addservice.
sm->addService(String16("service.test"),new Test ());
把我们提供的bbinder提供给servicemanager,前面的那个名字必须是唯1的.
IPCThreadState::self()->joinThreadPool();
有了joinThreadPool以后,我们就能够延续的提供服务了.
2 看1下test这个类的实现
test.h
class Test : public BnTest{
public:
inline uint32_t getTest(){
ALOGD("getTest===== %d",IPCThreadState::self()->getCallingUid());
return value;
}
inline void setTest(uint32_t par){
ALOGD("setTest===== %d",IPCThreadState::self()->getCallingUid());
value = par;
}
private:
uint32_t value;
};
我们的test类是继承了BnTest,它是具体的干活的类
ITest.h
class ITest : public IInterface{
public:
DECLARE_META_INTERFACE(Test);
virtual uint32_t getTest() = 0;
virtual void setTest(uint32_t ) = 0;
};
class BnTest : public BnInterface<ITest>{
public:
virtual status_t onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags= 0 );
};
ITest就相当因而aidl的接口定义了
ITest.cpp
enum{
GET_Test = 1,
SET_Test,
};
class BpTest: public BpInterface<ITest>{
public:
BpTest(const sp<IBinder>& impl)
: BpInterface<ITest>(impl){
}
virtual uint32_t getTest(){
Parcel data,reply;
data.writeInterfaceToken(ITest::getInterfaceDescriptor());
remote()->transact(GET_Test,data,&reply);
return reply.readInt32();
}
virtual void setTest(uint32_t params){
Parcel data,reply;
data.writeInterfaceToken(ITest::getInterfaceDescriptor());
data.writeInt32(params);
remote()->transact(SET_Test,data,&reply);
return;
}
};
IMPLEMENT_META_INTERFACE(Test,"android.Test.ITest");
status_t BnTest::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags){
switch(code){
case GET_Test:{
CHECK_INTERFACE(ITest,data,reply);
reply->writeInt32(getTest());
return NO_ERROR;
}break;
case SET_Test:{
CHECK_INTERFACE(ITest,data,reply);
uint32_t value = data.readInt32();
setTest(value);
return NO_ERROR;
}break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
而ITest几近也是照着模板写的,Google自己肯定写了类似于aidl的工具来生成native的service.