转自http://blog.csdn.net/zfzf294990051/article/details/7361081
本文为前篇 为android添加核心服务的具体实现
实现功能:添加一个底层服务到系统中,该服务名为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 {
- 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.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){
- 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();
- 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";
-
- @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/ActivityMana