实现功能:添加一个底层服务到系统中,该服务名为AddService,实现对传入参数加10000的操作。
1、创建一系列文件夹
cd framework/base
mkdir addservice
cd addservice
mkdir addserver 存放服务的启动程序文件,最终生成为可执行文件
mkdir libaddservice 存放服务动态链接库文件,最后生成一个动态链接库,供可执行程序使用。
2、编写动态库文件,服务的具体实现文件
cd libaddservice
AddService.h
#ifndef ANDROID_ADD_SERVICE_H
#define ANDROID_ADD_SERVICE_H
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/threads.h>
namespace android{
class AddService : public BBinder { //从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);
};
};//namespace
#endif
AddService.c
#include "AddService.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
namespace android{
static struct sigaction oldact;
static pthread_key_t sigbuskey;
//把自己注册到系统中
int AddService::instantiate(){
LOGE("*******AddService instantiate.*********");
int r = defaultServiceManager()->addService(String16("zhang"),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){//根据不同的code执行不同操作
case 0:{
pid_t pid = data.readInt32();
int num = data.readInt32();
num = num+10000;
reply->writeInt32(num);
return NO_ERROR;
break;
}
default:{
break;
}
}
return BBinder::onTransact(code,data,reply,flags);
}
};
注意在AddService::Instantiate()中调用defaultServiceManager()->addService("zhang",new AddService()),在服务总管ServiceManager中注册了名字为"zhang"的服务。在应用层取得该服务的句柄用ServiceManger.getService("zhang")来实现的。ServiceManager根据名字返回给客户端相应的服务,如果找不到该名字对应的服务,则返回空。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
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)
编译 mmm frameworks/base/addservice/libaddservice/
生成libAdd.so库文件
make:进入目录'/home/zhangfang/zf/DM3730/source/android_source/TI_Android_GingerBread_2_3_4Sources'
target thumb C++: libAdd <= frameworks/base/addservice/libaddservice/AddService.cpp
target SharedLib: libAdd (out/target/product/omap3evm/obj/SHARED_LIBRARIES/libAdd_intermediates/LINKED/libAdd.so)
target Non-prelinked: libAdd (out/target/product/omap3evm/symbols/system/lib/libAdd.so)
target Strip: libAdd (out/target/product/omap3evm/obj/lib/libAdd.so)
Install: out/target/product/omap3evm/system/lib/libAdd.so
3、编写可执行程序
cd addserver
vi addserver.cpp
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/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();
LOGV("*********AddServer*******: ServiceManager:%p",sm.get());
AddService::instantiate();//把自己添加到ServiceManager中去
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
关键是调用AddService::instantiate()把AddService服务注册进ServiceManager中。其他实现android都把它封装好了,与其他类型服务相同。参照:MediaPlayServer的实现。Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := addserver.cpp
LOCAL_SHARED_LIBRARIES := libAdd \
libutils \
libbinder
LOCAL_MODULE := addserver
include $(BUILD_EXECUTABLE)
编译:mmm frameworks/base/addservice/addserver/
生成可执行文件addserver.
make:进入目录'/home/zhangfang/zf/DM3730/source/android_source/TI_Android_GingerBread_2_3_4Sources'
target thumb C++: addserver <= frameworks/base/addservice/addserver/addserver.cpp
target Executable: addserver (out/target/product/omap3evm/obj/EXECUTABLES/addserver_intermediates/LINKED/addserver)
target Non-prelinked: addserver (out/target/product/omap3evm/symbols/system/bin/addserver)
target Strip: addserver (out/target/product/omap3evm/obj/EXECUTABLES/addserver_intermediates/addserver)
Install: out/target/product/omap3evm/system/bin/addserver
4、把生成的可执行文件addserver 和动态链接库文件libAdd.so拷贝到卡发版/system/bin和/system/lib目录(模拟器上相当于make snod.)
修改启动脚本init.rc文件,使之在开机是启动服务addserver
#service addservice is a test
service addserver_zhang /system/bin/addserver
这里的名字addserver_zhang不重要,方便自己识别而已,可随便写。
5、重新开机,执行ps看是否该服务已成功启动。
ps
1131 0 0:00 /system/bin/addserver
若能查询到addserver,则表名服务启动成功。
注意:查询不到,检查addserver是否写成addservice了。
6、编写应用程序测试该服务
package com.add.service;
import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
import android.util.Log;
import android.os.ServiceManager;
public class DM3730ADDServiceActivity extends Activity {
private static final String Tag = "com.add.service.test";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
test();
}
private void test()
{
try{
IBinder binder = ServiceManager.getService("zhang");
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){
e.printStackTrace();
}
}
}
注:本应该在framwork层添加一个java层的service,把这些具体的实现封装起来,在App层就只有调用write(),read()就好了,这里只是简单的测试而已。android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := AddServiceTest
include $(BUILD_PACKAGE)
编译之后生成 AddServiceTest.apk
进行安装,查看log
logcat
调用成功
I/ActivityManager( 1236): Start proc com.add.service for activity com.add.service/.DM3730ADDServiceActivity: pid=2104 uid=10034 gids={}
D/com.add.service.test( 2104): result = 10100
I/ActivityManager( 1236): Displayed com.add.service/.DM3730ADDServiceActivity: +147ms