阅读更多

 Android添加底层核心服务

1.      为什么要写底层核心服务呢?

          因为底层核心服务是  Android框架里最接近  Linux/Driver的部分。为了充分发挥硬件设备的差异化特性,核心服务是让上层  Java应用程序来使用  Driver/HW Device 特色的重要管道。例如  Media  Telephone等底层硬件。

        在开机过程中,就可以启动核心服务(汉字输入法服务等),让众多应用程序来共同使用。

由于共用,所以能有效降低  Java应用程序的大小(  Size)。

2.      核心服务与  Java 层的  Service有何区别和关系?

        Android具有两层服务

              --Java  SDK-based Service

              --C++层的  Code Service

    


3.  编写自己的核心服务(   C++   层)

1).   要点

       核心服务通常在独立的进程(   Process   )里执行。

       必须提供   IBinder   接口,让应用程序可以进行跨进程的绑定(   Binding   )和调用。

       因为共用,所以必须确保多线程安全(   Thread-safe   )。

使用   C++   来实现,并调用   IServiceManager::addService()   函数添加到系统的   Binder Driver   里。

上层应用程序通过   ServiceManager   获取该服务。

上层应用程序通过   IBinder::transact()   函数来与核心服进行数据交互。

2).   添加服务

下面详细介绍如何添加一个底层服务到系统中,假设服务名为   AddService   ,其用途是对传入的参数加上   1000   ,并返回结果。

服务实现

       进入   android   源码  的目录   frameworks/base   ,在该目录下建立自己的目录,假设为   addservice   ,再在这个目录中建立两个子目录   addserver     libaddservice     addserver   用于存放服务的启动文件,其最终的生成为可执行文件,在系统启动的时候运行,   libaddservice   用于存放服务的实现文件,最终会生成动态链接库,有   addserver   调用。

 

首先,服务的实现文件包括两个文件,      AddService.h     AddService.cpp  

以下是   AddService.h  

#ifndef ANDROID_GUILH_ADD_SERVICE_H

#define ANDROID_GUILH_ADD_SERVICE_H

 

#include

#include

#include

#include

 

namespace android {

         class AddService : public BBinder{//     BBinder   派生,实现本地接口

        

                 public:

                 static int instantiate();

                 AddService();

                 virtual ~AddService();

                 virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);

         };

}; //namespace

#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());//   这里主要是把   //AddSerice   这个服务添加到   Binder Driver   中服务名为   guilh.add

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");

}

//   这个是服务具体的本地实现,功能实现都应该放在这里面,通过传入执行代码(   code     //   的不同来执行不同的操作,上层隐射为不同的   api  

status_t AddService::onTransact(

uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){

switch(code) {

case 0: {//   根据   code   的不同执行不同的操作

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);

}

}}; //namespace

 

以下是编译服务的   Android.mk   ,和上面的   cpp   放在一起。

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= /

AddService.cpp

LOCAL_C_INCLUDES := /

$(JNI_H_INCLUDE)

LOCAL_SHARED_LIBRARIES :=      /

         libcutils              /

         libutils               /

         libbinder              /

         libandroid_runtime

LOCAL_PRELINK_MODULE := false

LOCAL_MODULE := libAdd

include $(BUILD_SHARED_LIBRARY)    #这一行表示编译为动态库

 

在命令行中退出到  android/目录级  加载编译环境  . build/envsetup.sh

然后  lunch

然后在   cd   /android/frameworks/base/addservice/   libaddservice/   目录   输入   mm

之后在   out   目录产出   libAdd.so   文件。

在此   完成核心服务第一步。

 

服务进程实现

                 进入到  cd   /android/frameworks/base/addservice/addserver/   目录

增加一个文件   addserver.cpp   ,文件内容如下:

 

#include

#include

#include

#include

#include

#include

#include

#include

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

//#include

using namespace android;

int main(int argc, char** argv)

{

sp proc(ProcessState::self());

sp sm = defaultServiceManager();//取得  ServiceManager

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

AddService::instantiate();//把自己添加到  ServiceManager

ProcessState::self()->startThreadPool();//启动缓冲池

IPCThreadState::self()->joinThreadPool();//这里是把服务添加到  Binder闭合循环进程中

}

以上为底层服务的标准操作。

下面是这个服务  makefile

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= /

         addserver.cpp

 

LOCAL_SHARED_LIBRARIES := /

         libAdd /

         libutils /

         libbinder

LOCAL_MODULE:= addserver

include $(BUILD_EXECUTABLE)//编译为可执行文件

退出后当前目录执行  mm即可在  out目录的  system/bin下产出  addserver可执行文件。

实现服务进程开机自动运行

进入到  /android/system/core/rootdir/目录中有个  init.rc文件

vi init.rc

 service中添加

service addservice     /system/bin/addserver     //  /system/bin/addserver作为一个服务启动,服务的名称为  addservice(这个不重要)。

 

最后退出到  android/目录下执行全编译:

输入  . build/envsetup.sh

Lunch

Make

完成之后

Emulator打开模拟器

打开另一个  shell终端  输入  adb shell     进入模拟器模式        如果  adbshell系统提示没有发现该命令  就在  android/out/host/linux-x86/bin/中输入     ./adb shell  

在输入  ps   查看进程     找到是否有  addserver进程

如果有就成功一半。

 

 

测试我们的服务

 

随便在   android/packages/apps     建立一个简单的应用程序,

这里可以直接在  eclipse  中建立好工程  拷贝到  android/packages/apps  中,然后为应用添加一个  Android.mk  文件,可以从其他应用中拷贝来修改。

在应用程序中测试服务的代码:

     private void test(){

                 try{

                         IBinder binder = ServiceManager.getService("guilh.add");//  取得服务

                         Parcel data = Parcel.obtain();

                         Parcel reply = Parcel.obtain();

                         if(binder == null)

                                 Log.d(TAG,"failed to get service");

                         data.writeInt(Process.myPid());//  固定操作

                         data.writeInt(100);//  传入参数

                         binder.transact(0, data, reply, 0);//  执行远程调用

                         Log.d(TAG,"result="+reply.readInt());//   验证结果

                 }catch(Exception e){

                           Log.d(TAG,e.toString());

                 }

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android各个support library特征和区别(官方文档)
  6. Android番外篇——XML layout与CSS 转载
  7. Power Supply 文件节点和电池服务属性对照
  8. Android应用程序UI硬件加速渲染技术
  9. Android(安卓)NDK开发两部曲(一)之初识篇(JNI通识与NDK配置)

随机推荐

  1. android 相对布局中的 控件布局
  2. android 将鼠标右键点击事件改为点击后返
  3. Android中子布局填充ScrollView
  4. Android中webview跟JAVASCRIPT中的交互
  5. Android编译系统学习总结
  6. Android获取经纬度
  7. android振动效果的实现
  8. 【android】以前没有注意的一个ListActiv
  9. (转帖)Android系列之Wifi定位
  10. Android处理后台返回数据——Json转实体