现在的位置: 首页 > 综合 > 正文

转载:Android service 实现过程

2014年01月04日 ⁄ 综合 ⁄ 共 6620字 ⁄ 字号 评论关闭

大多是高老师的东西,我是边学边干,呵呵。话说Android还是1.5的时候......

 

一、
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 <utils.h>

#include <utils/RefBase.h>

#include <utils/IInterface.h>

#include <utils/Parcel.h>

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 <utils/IServiceManager.h>

#include <utils/IPCThreadState.h>

 

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, reply, flags);


             
}


      
}


};

 

Android.mk

文件:

 

LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= AddService.cpp

 

#LOCAL_C_INCLUDES:= $(JNI_H_INCLUDE)   


 

LOCAL_SHARED_LIBRARIES:= libutils

 

LOCAL_MODULE:= libAddService

 

LOCAL_PRELINK_MODULE:= false

 

include $(BUILD_SHARED_LIBRARY)

 

Step-2

:以
C++

撰写一个可独立执行的
addserver.cpp

程序,它的用途是:诞生一个
AddService

类别之对象,然后将该对象参考存入
Binder Driver

里。其内容为:

addserver.cpp

文件:

#include <sys/types.h>

#include <unistd.h>

#include <grp.h>

#include <utils/IPCThreadState.h>

#include <utils/ProcessState.h>

#include <utils/IServiceManager.h>

#include <utils/Log.h>

#include <private/android_filesystem_config.h>

#include "../libaddservice/AddService.h"

 

using namespace android;

 

int main(int argc, char** argv)

{

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();

LOGI("ServiceManager: %p", sm.get());

AddService::instantiate();

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

 

Android.mk

文件:

LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= addserver.cpp

 

LOCAL_SHARED_LIBRARIES:= libutils libAddService

 

LOCAL_MODULE:= addservice

 

include $(BUILD_EXECUTABLE)

 

Step-3

:编译上述两个文件分别产出了
libAdd.so

类别库和
addserver

可执行程序。接着将
libAdd.so

拷贝到
Android

仿真器的
/system/lib/

里;也把
addserver

拷贝到
/system/bin/

里。

 

Step-4

:执行
addserver

。其中的指令:
AddServer::instantiate()

就执行到
AddServer

类别的
instantiate()

函数,其内容为:

int AddService::instantiate() {

LOGE("AddService instantiate");

int r = defaultServiceManager()->addService(

String16("guilh.add"), new AddService());

LOGE("AddService r = %d/n", r);

return r;

}

其先执行到
new AddServer()

,就诞生一个
AddServer

类别之对象;

接着,呼叫
defaultServiceManager()

函数取得
SM


IServiceManager

接口;

再呼叫
IServiceManager::addServer()

将该对象参考存入
Binder Driver

里。

 

Step-5

:这样就成功地将
AddService

服务加入到
Binder Driver

里了。现在就可以写个
Add

类来使用
AddService

核心服务了。以
C++

撰写
Add

类别,其完整程序代码为:

Add.h

文件:

#ifndef ANDROID _ADD_H

#define ANDROID _ADD_H

namespace android {

      
class Add {


             
public:


                    
int setN(int n);


             
private:


                    
static const void getAddService();


      
};


}; //namespace

#endif // ANDROID _ADD_H

 

Add.cpp

文件:

#include <utils/IServiceManager.h>

#include <utils/IPCThreadState.h>

#include "Add.h"

 

namespace android {

      
sp<IBinder> binder;


      
int Add::setN(int n){


             
getAddService();


             
Parcel data, reply;


             
data.writeInt32(getpid());


             
data.writeInt32(n);


 

             
LOGE("BpAddService::create remote()->transact()/n");


             
binder->transact(0, data, &reply);


             
int i = reply.readInt32();


             
return i;


      
}


      
const void Add::getAddService(){


             
sp<IServiceManager> sm = defaultServiceManager();


             
binder = sm->getService(String16("guilh.add"));


             
LOGE("Add::getAddService %p/n",sm.get());


             
if (binder == 0) {


                    
LOGW("AddService not published, waiting...");


                    
return;


             
}


      
}


 

};

 

Android.mk

文件:

LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:=Add.cpp

 

LOCAL_SHARED_LIBRARIES := libutils libAddService

 

LOCAL_MODULE := libAdd

 

LOCAL_PRELINK_MODULE:= false

 

include $(BUILD_SHARED_LIBRARY)

 

Step-6

:下面写个
JNI Native

类别来使用
Add

类别之对象。透过
JNI Native

函数,就可以与
Java

层的
Service

服务衔接起来。

首选使用
javah

命令生成相应头文件。

com_hello_Service_MySer.h

文件:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_hello_Service_MySer */

 

#ifndef _Included_com_hello_Service_MySer

#define _Included_com_hello_Service_MySer

#ifdef __cplusplus

extern "C" {

#endif

/*

 
* Class:    
com_hello_Service_MySer


 
* Method:   
intFromJNI


 
* Signature: ()I


 
*/


JNIEXPORT jint JNICALL Java_com_hello_Service_MySer_intFromJNI

 
(JNIEnv *, jobject);


 

#ifdef __cplusplus

}

#endif

#endif

然后实现相应函数。

com_hello_Service_MySer.cpp

文件:

#include <jni.h>

#include <JNIHelp.h>

#include "../libadd/Add.h"

#include "com_hello_Service_MySer.h"

 

JNIEXPORT jint JNICALL Java_com_hello_Service_MySer_intFromJNI(JNIEnv * env, jobject thiz)

{

   
android::Add myadd;


      
int r = myadd.setN(5);


      
return r;


}

 

Android.mk

文件:

LOCAL_PATH:= $(call my-dir)

 

include $(CLEAR_VARS)

抱歉!评论已关闭.