文档章节

Android通过编译源代码提供系统服务-android学习之旅(85)

fengsehng
 fengsehng
发布于 2016/11/09 09:08
字数 1097
阅读 3
收藏 0

通过编译android4.1.2的源代码,添加一个FregServer的系统服务,以及一个服务代理FregClient

具体分为三部分,client,common,server,common中规定了client和common的接口,和一些公共方法

client部分代码

#define LOG_TAG "FregTest"

#include <utils/Log.h>
#include <binder/IServiceManager.h>

#include "../common/IFregService.h"

int main()
{
    IServiceManager = defaultServiceManager();
    sp<IBinder> binder = defaultServiceManager()->getService(String16(FREG_SERVICE));       //通过servicemanager获取名为xxx的Service的BpBinder代理对象
    if(binder == NULL) {
        ALOGE("[C] Failed to get freg service: %s.\n", FREG_SERVICE);
        return -1;
    }
    ALOGE("[C] Got BpBinder");
    sp<IFregService> service = IFregService::asInterface(binder);                           //将bpbinder代理对象封装为bpfregservice对象
    if(service == NULL) {
        ALOGE("[C] Failed to get freg service interface.\n");
        return -2;
    }
    ALOGE("[C] Got BpFregService");
    ALOGE("[C] Reading original value from FregService.\n");

    int32_t val = service->getVal();
    ALOGE("[C] Result: %d.\n", val);        

sleep(15);

    ALOGE("[C] Add value 1 to FregService.\n");
    val += 1;
    service->setVal(val);

    ALOGE("[C] Reading the value from FregService again:\n");

    val = service->getVal();
        ALOGE("[C] Result: %d.\n", val); 

    return 0;
}

mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := ../common/IFregService.cpp \
    FregClient.cpp

LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder

LOCAL_MODULE := FregClient

include $(BUILD_EXECUTABLE)

Server部分

#define LOG_TAG "FregTest"

#include <stdlib.h>
#include <fcntl.h>

#include <utils/Log.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

#include "../common/IFregService.h"

#define FREG_DEVICE_NAME "/dev/freg"

class FregService : public BnFregService
{
public:
    FregService()
    {
        val = 0;
        ALOGE("[S] Tread: %d. In FregService().", gettid());
    }

    virtual ~FregService()
    {
        ALOGE("[S] Tread: %d. In ~FregService().", gettid());
    }

public:
    static void instantiate()
    {
        defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());     //获取servicemanager并调用addService函数实现服务注册
        ALOGE("[S] Tread: %d. instantiate(), addService-%s", gettid(), FREG_SERVICE);
    }

    int32_t getVal()
    {
        ALOGE("[S] Tread: %d. In getVal(), val-%d returned.", gettid(), val);
        return val;
    }

    void setVal(int32_t v)
        {
                val = v;
        ALOGE("[S] Tread: %d. In setVal(), val-%d set.", gettid(), val);
        }

private:
    int val;
};

int main(int argc, char** argv)
{
    FregService::instantiate();     

    ProcessState::self()->startThreadPool();    //启动线程池
ALOGE("[S] Tread: %d. ProcessState::self()->startThreadPool() finished.", gettid());
    IPCThreadState::self()->joinThreadPool();   //将主线程加入线程池
ALOGE("[S] Tread: %d. IPCThreadState::self()->joinThreadPool(); finished.", gettid());

    return 0;
}
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := ../common/IFregService.cpp \
    FregServer.cpp

LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder

LOCAL_MODULE := FregServer

include $(BUILD_EXECUTABLE)

common部分

#define LOG_TAG "IFregService"

#include <utils/Log.h>

#include "IFregService.h"

using namespace android;

enum 
{
    GET_VAL = IBinder::FIRST_CALL_TRANSACTION,
    SET_VAL
};

class BpFregService: public BpInterface<IFregService>       //通信请求的发送
{
public:
    BpFregService(const sp<IBinder>& impl) 
        : BpInterface<IFregService>(impl)
    {

    }

public:
    int32_t getVal()
    {
        Parcel data;
        data.writeInterfaceToken(IFregService::getInterfaceDescriptor());   //获取了Ifregservice的接口名,并调用了parcel.writeInterfaceToken函数写入了data中

        Parcel reply;
        remote()->transact(GET_VAL, data, &reply);      //remote获取bpbinder代理对象,通过transact函数来发送请求

        int32_t val = reply.readInt32();

        return val;
    }

    void setVal(int32_t val)
        {
                Parcel data;
                data.writeInterfaceToken(IFregService::getInterfaceDescriptor());
                data.writeInt32(val);

                Parcel reply;
                remote()->transact(SET_VAL, data, &reply);
        }

};

IMPLEMENT_META_INTERFACE(FregService, "hikame.IFregService");//见最下

status_t BnFregService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)        //通信数据的接收与处理
{
    switch(code)
    {
        case GET_VAL:
        {
            CHECK_INTERFACE(IFregService, data, reply);

            int32_t val = getVal();
            reply->writeInt32(val);

            return NO_ERROR;
        }
        case SET_VAL:
                {
                        CHECK_INTERFACE(IFregService, data, reply);

            int32_t val = data.readInt32();
            setVal(val);

                        return NO_ERROR;
                }
        default:
        {
            return BBinder::onTransact(code, data, reply, flags);
        }
    }
}
/*IFregService的具体实现 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const android::String16 I##INTERFACE::descriptor(NAME); \ const android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const android::sp<android::IBinder>& obj) \ { \ android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } \ */
#ifndef IFREGSERVICE_H_
#define IFREGSERVICE_H_

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

#define FREG_SERVICE "hikame.FregService" //Service名称

using namespace android;                            //在各个头文件中namespace为android的代码部分都被使用了

class IFregService: public IInterface
{
public:
    /*
#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface( \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE(); \
    virtual ~I##INTERFACE(); \
    定义了构造函数和析构函数,descriptor是接口名,getInterfaceDescriptor是获取该接口名的函数
    ??这个android::sp是什么?A:/include/utils/StrongPointer.h
    */
    DECLARE_META_INTERFACE(FregService);
    virtual int32_t getVal() = 0;
    virtual void setVal(int32_t val) = 0;
};

class BnFregService: public BnInterface<IFregService>
{
public:
    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};

#endif

好了放他们放到android-4.1.2_r1-JZO54K\external\binder目录下, external目录下可以放这些外来的服务

执行编译命令

1.通过xShell连接到远程的ubuntu服务器,里面下载了Android源代码

2.cd 到相应版本源代码的根目录

3.执行source build/envsetup.sh初始化环境

4.执行mmm ./external/binder/server/

5.执行mmm ./external/binder/client/ ,分别编译两个模块

6然后在out/target/product/gerneric/system/bin目录底下,查看相应的生成文件

下一步是把相应的服务文件拷贝到手机的/data/local/tmp目录下

1.代开adb shell,执行su,进入root模式

2.在服务文件的目录,按住shift右键,打开命令窗口

3.输入adb push FregServer /data/local/tmp,adb push FregClient /data/local/tmp,拷贝到相应的目录

4.su进入root模式,进入 /data/local/tmp目录,执行./FregClient

5.查看日志adb logcat FregTest:i *:s

部分截图

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

本文转载自:http://blog.csdn.net/lpjishu/article/details/49765509

共有 人打赏支持
fengsehng
粉丝 4
博文 284
码字总数 214494
作品 0
朝阳
程序员
Android系统源代码分析步骤

目前,互联网行业正在朝着移动互联网方向强劲地发展,而移动互联网的发展离不开背后的移动平台的支撑。众所周知,如今在移动平台市场上,苹果的iOS、谷歌的Android和微软的Windows Phone系统...

紫地瓜
2012/11/19
0
0
最强最全干货分享:Android开发书籍、教程、工具等

最全干货分享,本文收集整理了Android开发所需的书籍、教程、工具、资讯和周刊各种资源,它们能让你在Android开发之旅的各个阶段都受益。 入门 《Learning Android(中文版)》 本书为Andro...

拉偶有所依
2015/01/09
0
1
Android 源码分析之旅1--系统架构与分析方法、工具

《Android 源码分析之旅》目录 apefwkall.png 《Android 源码分析之旅》的全部目录将作如下安排: 第1章节——本篇文章,将介绍一些基本的概念、方法、工具。 第2章节——着重介绍Binder IP...

猴亮屏
2017/10/19
0
0
Android应用程序的Activity启动过程简要介绍和学习计划

在Android系统中,Activity和Service是应用程序的核心组件,它们以松藕合的方式组合在一起构成了一个完整的应用程序,这得益于应用程序框架层提供了一套完整的机制来协助应用程序启动这些Act...

坚持自己
2013/03/28
0
0
Android: NDK编程入门笔记

为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。 2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C...

gongweixin
2013/04/23
0
3

没有更多内容

加载失败,请刷新页面

加载更多

下一页

kernel version does not match DSO version

错误信息: kernel version 384.11 does not match DSO version 384.130.0 原因是: cuda driver版本太低,不匹配DSO 简单有效的修复方法,升级nvidia driver, 步骤如下: 1. google seach ...

刘小米
今天
0
0
maven坐标和依赖

一、maven坐标详解 <groupId>com.fgt.club</groupId><artifactId>club-common-service-facade</artifactId><version>3.0.0</version><packaging>jar</packaging> maven的坐标元素说......

老韭菜
今天
1
0
springmvc-servlet.xml配置表功能解释

问:<?xml version="1.0" encoding="UTF-8" ?> 答: xml version="1.0"表示是此xml文件的版本是1.0 encoding="UTF-8"表示此文件的编码方式是UTF-8 问:<!DOCTYPE beans PUBLIC "-//SPRING//......

隐士族隐逸
今天
1
0
基于TP5的微信的公众号获取登录用户信息

之前讲过微信的公众号自动登录的菜单配置,这次记录一下在TP5项目中获取自动登录的用户信息并存到数据库的操作 基本的流程为:微信设置自动登录的菜单—>访问的URL指定的函数里获取用户信息—...

月夜中徘徊
今天
0
0
youTrack

package jetbrains.teamsys.license.runtime; 计算lis package jetbrains.ring.license.reader; 验证lis 安装后先不要生成lis,要把相关文件进行替换 ring-license-checker-1.0.41.jar char......

max佩恩
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部