如何在android 4.0.3中添加系统服务

 

参考实作:http://blog.csdn.net/belyxiong/article/details/5875993  为android添加底层核心服务

参考博文中信息不全且有小小问题,本文对整个过程稍作整理并对内容作了补全和修正。

 

user@ubuntu:/$ sudo adb shell

root@android:/ # cd system/lib               --> 服务的库文件

root@android:/ # cd system/bin               --> 服务的可执行文件

root@android:/ # cat init.rc                    --> 服务的配置文件

 

服务启动过程:

在init.rc里添加service,这样就会调用服务的可执行文件,将服务加到ServiceManager中,这样,应用就可以获取服务方法。

 

下面ubuntu当前目录为:整个android4.0工程根目录,包含frameworks,system,packages等子目录。

 

1、自定义服务MyService库

$ mkdir -p frameworks/base/MyService/libmyservice

$ cd frameworks/base/MyService/libmyservice

$ touch Android.mk MyService.h MyService.cpp

 

Android.mk内容:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= MyService.cpp
LOCAL_MODULE := libMyService
LOCAL_MODULE_TAGS := optional

LOCAL_C_INCLUDES := \
        $(JNI_H_INCLUDE)

LOCAL_SHARED_LIBRARIES :=     \
        libcutils             \
        libutils              \
        libbinder             \
        libandroid_runtime

LOCAL_PRELINK_MODULE := false

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


 

注意: LOCAL_MODULE_TAGS那一行要写在两个include $中间

 

MyService.h内容:

#ifndef ANDROID_GUILH_MY_SERVICE_H
#define ANDROID_GUILH_MY_SERVICE_H

#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/threads.h>

namespace android {
  class MyService : public BBinder{// 从 BBinder 派生,实现本地接口
     public:
     static int instantiate();
     MyService();
     virtual ~MyService();
     virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
   };
}; //namespace

#endif


 

MyService.cpp内容:

#include "MyService.h"
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

namespace android {
    static struct sigaction oldact;
    static pthread_key_t sigbuskey;

    // 把自己注册到系统中
    int MyService::instantiate() {
        LOGE("MyService::instantiate");
// 这里主要是把 
//MySerice 这个服务添加到 Binder Driver 中服务名为 guilh.MyService
        int r = defaultServiceManager()->addService(
            String16("guilh.MyService"), new MyService());
        
        LOGE("MyService r = %d/n", r);
        return r;
    }

    // 构造函数
    MyService::MyService()
    {
        LOGE("MyService created");
        pthread_key_create(&sigbuskey, NULL);
    }

    // 析构函数
    MyService::~MyService()
    {
        pthread_key_delete(sigbuskey);
        LOGE("MyService destroyed");
    }

// 这个是服务具体的本地实现,功能实现都应该放在这里面,通过传入执行代码( code ) 
// 的不同来执行不同的操作,上层隐射为不同的 api 。
    status_t MyService::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){

        LOGE("MyService::onTrascat");
        switch(code) {
        // 只处理 code == 0 的情况        case 0:
            {// 读取data中的整数,并对它做加1000的操作,然后将结果写到reply中
                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


 

然后用mmm编译生成libMyService.so,

$ adb push out/target/product/xxx/system/lib/libMyService.so /system/lib/

根据工程替换上方的xxx。

 2、自定义服务MyService可执行文件,myserver

$ mkdir -p frameworks/base/MyService/myserver

$ cd frameworks/base/MyService/myserver

$ touch Android.mk MyServer.cpp

Android.mk内容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= MyServer.cpp

LOCAL_SHARED_LIBRARIES := \
        libMyService \
        libutils \
        libbinder

LOCAL_MODULE:= myserver
LOCAL_MODULE_TAGS:= optional

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


 

MyServer.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 "../libmyservice/MyService.h"


using namespace android;

int main(int argc, char** argv)
{
    LOGE("MyServer::main");
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();//取得 ServiceManager

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

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

    ProcessState::self()->startThreadPool();//启动缓冲池
    IPCThreadState::self()->joinThreadPool();//这里是把服务添加到 Binder闭合循环进程中
}


 

然后用mmm编译生成myserver,

$ adb push out/target/product/xxx/system/bin/myserver /system/bin/

 

3、修改init.rc

$ cd system/core/rootdir

编辑 init.rc,在末尾加上:

# MyService

service myserver /system/bin/myserver

        class main

        user root


$ make bootimage

$ sudo adb reboot bootloader

$ sudo fastboot flash boot out/target/product/xxx/boot.img

$ sudo fastboot reboot

 

4、运行MyService测试程序

$ cd packages/apps/

$ android list

根据结果将下面命令的id替换成合适的值。

$  android create project --target id --name MyServiceTest --path MyServiceTest --activity MyServiceTestActivity --package com.example.myapp

$ cd MyServiceTest

$ vi Android.mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_PACKAGE_NAME := MyServiceTest
LOCAL_CERTIFICATE := platform

#LOCAL_SDK_VERSION := current

LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags

include $(BUILD_PACKAGE)

# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))



$ vi res/layout/main.xml

删掉<TextView>中的 android:text那行,否则会因为语言编译不通过。

或者在 Android.mk 中加上 tests: LOCAL_MODULE_TAGS := optional tests

 

$ vi src/com/example/myapp/MyServiceTestActivity.java

package com.example.myapp;

import android.app.Activity;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ServiceManager;
import android.os.Process;
import android.util.Log;

public class MyServiceTestActivity extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Log.d("MyService","MyService::onCreate");
        setContentView(R.layout.main);
        test();
    }

    private void test(){
        try{
            Log.d("Myservie","MyService::test");
            IBinder binder = ServiceManager.getService("guilh.MyService");// 取得服务
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();

            if(binder == null)
                Log.d("MyService","failed to get service");

            data.writeInt(Process.myPid());// 固定操作
            data.writeInt(100);// 传入参数
            binder.transact(0, data, reply, 0);// 执行远程调用
            Log.d("MyService","result="+reply.readInt());// 验证结果
        }catch(Exception e){
            Log.d("MyService",e.toString());
        }
    }
}



然后用mmm编译生成MyServiceTest,

$ adb install -r out/target/product/xxx/system/app/MyServiceTest.apk 

 

最后,在手机上运行MyServiceTest程序,

通过 logcat -s MyService 查看log,可以发现服务运行,测试成功获取服务。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值