Android实现一个Native C++服务的方案详解

在Android中实现一个Java服务非常简单,编写AIDL文件定义接口,然后定义一个类继承自Service并定义一个类实现AIDL中定义的接口即可,在C++中有办法用AIDL定义接口并实现一个服务供Java端和C++端访问吗?

在api-29之后是可以实现的,步骤如下:

1.添加AIDL文件:IFoundationService.aidl

目录相对路径为:aidl/com/free/device

package com.free.device;

interface IFoundationService
{
    int Function1();
    int Function2();
    int Function3();
}

2.实现FoundationService.h

#ifndef COM_FREE_DEVICE_FOUNDATION_SERVICE_H_
#define COM_FREE_DEVICE_FOUNDATION_SERVICE_H_

#include <stdlib.h>
#include <utils/RefBase.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <thread> 

#include "com/free/device/IFoundationService.h"
#include "com/free/device/BnFoundationService.h"

using namespace android;

class IFoundationServer : public com::free::device::BnFoundationService
{

public:
    IFoundationServer();
    virtual ~IFoundationServer();
    binder::Status function1(int32_t* _aidl_return);
    binder::Status function2(int32_t* _aidl_return);
    binder::Status function3(int32_t* _aidl_return);


private:
    //其他私有变量

private:    
    std::string getCurrentDateTime();
    //其他私有函数
};

#endif  // COM_FREE_DEVICE_FOUNDATION_SERVICE_H_

3.实现FoundationService.cpp

#define LOG_TAG "FoundationServiced"

#include "FoundationService.h"
#include <utils/Log.h>

#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <array>
#include <chrono>
#include <ctime>
#include <stdio.h>
#include <unistd.h>

#include <thread>
#include <atomic>
#include <signal.h>


using namespace android;

// 构造函数
IFoundationServer::IFoundationServer()  {}

// 析构函数
IFoundationServer::~IFoundationServer() {
    
}

//接口实现
binder::Status IFoundationServer::function1(int32_t* _aidl_return) {
    return binder::Status::ok();
}

// 停止Logcat日志记录
binder::Status IFoundationServer::function2(int32_t* _aidl_return) {
    return binder::Status::ok();
}

// 启用内核日志记录
binder::Status IFoundationServer::function3( int32_t* _aidl_return) {
    return binder::Status::ok();
}


// 获取当前日期和时间
std::string IFoundationServer::getCurrentDateTime() {
    auto now = std::chrono::system_clock::now();
    auto now_c = std::chrono::system_clock::to_time_t(now);
    std::array<char, 64> buf;
    std::strftime(buf.data(), buf.size(), "%Y%m%d%H%M%S", std::localtime(&now_c));
    return std::string(buf.data());
}

4.实现FoundationServiced.cpp,服务Damon进程的入库函数

#define LOG_TAG "FoundationServiced"

#include <stdlib.h>
#include <utils/RefBase.h>
#include <utils/Log.h>
#include <binder/TextOutput.h>
#include <binder/IInterface.h>
#include <binder/IBinder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>

#include "FoundationService.h"

using namespace android;

int main(int /*argc*/, char const ** /*argv*/)
{
    defaultServiceManager()->addService(String16("IFoundation"), new IFoundationServer());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return 0;
}

5.foundationservice.rc

service foundationservice /system/bin/foundationserviced
    class core
    user root
    group root

6.编写Android.bp

cc_library_shared {
    name: "libfoundationservice",

    srcs: [
        "aidl/com/free/device/IFoundationService.aidl",
        "FoundationService.cpp"
    ],
    aidl: {
      export_aidl_headers: true,
    },
    export_include_dirs: ["aidl"],
 
    include_dirs: ["frameworks/native"],
 
    shared_libs: [
        "libbinder",
        "libutils",
        "liblog",
    ],
 
    cflags: [
        "-Wall",
        "-Werror",
        "-Wunused",
        "-Wunreachable-code",
    ],
}

cc_binary {
    name: "foundationserviced",

    srcs: [
        "FoundationServiced.cpp",
    ],

    include_dirs: ["frameworks/native"],

    shared_libs: [
        "libfoundationservice",
        "libbinder",
        "libutils",
        "liblog",
    ],

    cflags: [
        "-Wall",
        "-Werror",
        "-Wunused",
        "-Wunreachable-code",
        "-Wunused-parameter",
    ],

    init_rc: ["foundationservice.rc"],
}

7.Selinux相关修改

修改private/service_contexts

foundationserviced              u:object_r:foundationserviced_service:s0

新增foundationserviced.te

# foundationserviced service
type foundationserviced, domain, coredomain;
type foundationserviced_exec, exec_type, file_type;
#binder_use(foundationserviced);

init_daemon_domain(foundationserviced);

allow foundationserviced foundationserviced_service:service_manager { add };

allow foundationserviced binder_device:chr_file { ioctl open read write };
allow foundationserviced servicemanager:binder call;

修改file_contexts

/system/bin/foundationserviced   u:object_r:foundationserviced_exec:s0

修改service.te

type foundationserviced_service, service_manager_type;

8.device.mk修改

PRODUCT_PACKAGES += \
                libfoundationservice \
                foundationserviced

9.client实现

Java客户端

private static final String SERVICE_MANAGER = "android.os.ServiceManager";
private static final String GET_SERVICE = "getService";
private static final String SERVICE_NAME = "IFoundation";
private void init() {
        IBinder binder = null;

        try {
            // 加载android.os.ServiceManager类,这是Android的一个系统服务管理类
            Class<?> serviceManager = Class.forName(SERVICE_MANAGER);
            
            // 从ServiceManager类中获取名为"getService"的方法,该方法用于获取服务的IBinder对象
            Method getServiceMethod = serviceManager.getDeclaredMethod(GET_SERVICE, String.class);
            
            // 调用getService方法,获取名为SERVICE_NAME 的服务的IBinder对象
            binder = (IBinder) getServiceMethod.invoke(null, SERVICE_NAME);
            
            // 检查获取的IBinder对象是否为空,如果为空则表示服务获取失败
            if (binder == null) {
                Log.d(TAG, "getService failed for " + SERVICE_NAME);
                return;  
            }            
           
            mFoundation = IFoundationService.Stub.asInterface(binder);
        } catch (Exception e) {            
            e.printStackTrace();
            Log.e(TAG, "meet exception: " + e.getMessage());
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值