Android service 实现过程
手机应用层 2010-05-08 00:21:08 阅读159 评论0字号:大中小
一、 Android Service介绍
Android的 Service分为两种: Android Service和 Native Service。
Android Service:又称为
Java Service,是实现在框架层( framework)里的 Server。 Android Service以 Java编写。
Native Service:又称为 System Service,是实现在 Runtime层里的 Server。
以 MediaPlayer为例,从下图我们可以得出两种服务的关系:
接下来要讨论的 Service是 Native Service,与应用程序
设计上所讨论的 Service( android.app.Service)不同。
二、为什么要写底层的核心服务呢?
( 1) 因为底层核心服务是 Android框架里最接近 Linux/Driver的部分。为了充分发挥硬件设备的差异化特性,核心服务是让上层 Java应用程序来使用 Driver/HW Device特色的重要管道。
( 2) 在开机过程中,就可以启动核心服务 (例如汉字输入法服务等 ),让众多应用程序来共享之。
( 3) 由于共享,所以能有效降低 Java应用程序的大小 (Size)。
三、如何实现一个核心服务呢 ?
要点如下:
( 1)核心服务通常在独立的进程 (Process)里执行。
( 2)必须提供 IBinder接口,让应用程序可以进行跨进程的绑定 (Binding)和呼叫。
( 3)因为共享,所以必须确保多线裎安全 (Thread-safe)。
( 4)以 C++类别定义,诞生其对象,透过 SM之协助,将该对象参考值传给 IServiceManager::addService()函数,就加入到 Binder Driver里了。
( 5)应用程序可透过 SM之协助而远距绑定该核心服务,此时 SM会回传 IBinder接口给应用程序。
( 6)应用程序可透过 IBinder::transact()函数来与核心服务互传数据。
四、 Server实现实践
下面以一个小例子来说明具体实现一个 Server的步骤。此实例功能为简单的整数加法 (Add)运算,我们将其命名 AddService。
Step-1:以 C++撰写 AddService类别,其完整程序代码为:
AddService.h文件:
#ifndef ANDROID_GUILH_ADD_SERVICE_H
#define ANDROID_GUILH_ADD_SERVICE_H
#include
#include
#include
#include
namespace android
{
class AddService : public BBinder
{
mutable Mutex mLock;
int32_t mNextConnId;
public:
static int instantiate();
AddService();
virtual ~AddService();
virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
};
}
#endif
AddService.cpp文件:
#include "AddService.h"
#include
#include
namespace android {
static struct sigaction oldact;
static pthread_key_t sigbuskey;
int AddService::instantiate() {
LOGE("AddService instantiate");
int r = defaultServiceManager()->addService(
String16("guilh.add"), new AddService());
LOGE("AddService r = %d\n", r);
return r;
}
AddService::AddService()
{ LOGV("AddService created");
mNextConnId = 1;
pthread_key_create(&sigbuskey, NULL);
}
AddService::~AddService()
{ pthread_key_delete(sigbuskey);
LOGV("AddService destroyed");
}
status_t AddService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
switch(code) {
case 0: {
pid_t pid = data.readInt32();
int num = data.readInt32();
num = num + 1000;
reply->writeInt32(num);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data,