研究与学习 4.0 · 优秀 2023-12-27 · 文章

Android11+ AIDL:专为提升应用性能而生!

Android11+ AIDL:专为提升应用性能而生! Android新版本AIDL性能再提升化! 点击下方👇关注Android系统攻城狮 每日充电:OS+MultiMedia学习之旅

打开原文回到归档

English

Android11+ AIDL:专为提升应用性能而生! 原创 saltfish saltfish Android系统攻城狮 在小说阅读器读本章 去阅读 在小说阅读器中沉浸阅读 点击下方👇关注 Android系统攻城狮每日充电:OS+MultiMedia学习之旅1.前言学习理念:一次理解一个知识点难度:★★★★☆源码环境:Android 12硬件环境:SDM845阅读时间:1.5分钟接着上一篇Android HAL发展历程:探索HAL到HIDL四个阶段的演进过程文章,我们已经介绍了HAL到HIDL发展的历程。Android11版本开始,AIDL引入实现HAL同样的功能,可以调用HAL,也可以直接和内核驱动通信。下面看一下HIDL和AIDL通信过程,AIDL比起传统通信方式有哪些优点?接着实现一个AIDL实现用例,读者可以和上一篇文章HIDL实现服务做一个对比,看看它们之间的差异在哪里?1.先看一个HIDL模式通信路线图:图一2.再看一个AIDL模式通信路线图:图二通过图一和图二比较,就能知道谷歌为什么要在Android 10以后逐渐去除HIDL通信模式。AIDL优势很明显,它在应用端直接获取AIDL Service后,可以直接给AIDL的服务端发送IPC通信,在服务端直接调用HAL的API或者直接通过open("/dev/xxx")与驱动通信。与传统的AIDL比起来,中间少了两三个通信环节,效率会显著提升。下面写一个AIDL使用Binder IPC通信的例子。2.AIDL客户端1.创建aidl接口# mkdir -p hardware/interfaces/invcase/aidl/android/hardware/invcase# emacs IInvcase.aidlpackage android.hardware.invcase; @VintfStabilityinterface IInvcase {    String getChars();    void putChars(in String msg);}2.创建Android.bp# cd hardware/interfaces/invcase/aidl# emacs Android.bpaidl_interface {    name: "android.hardware.invcase",    vendor: true,    srcs: ["android/hardware/invcase/*.aidl"],    stability: "vintf",    owner: "vqtrong",    backend: {        cpp: {            enabled: false,        },        java: {            sdk_version: "module_current",        },    },}3.编译与配置1.执行以下命令:编译报错# mmm hardware/interfaces/invcase/aidl 2.执行以下操作后,再编译aidl# m android.hardware.invcase-update-api -j12 3.再编译aidl# mmm hardware/interfaces/invcase/aidl 4.将invacase模块配置编译到系统# emacs build/make/target/product/base_vendor.mkPRODUCT_PACKAGES += android.hardware.invcase 到此AIDL客户端创建完成,接下来创建AIDL Server端。3.AIDL Server端1.AIDL对应Server端头文件实现# emacs hardware/interfaces/invcase/aidl/default/Invcase.h#pragma once#include <aidl/android/hardware/invcase/BnInvcase.h>namespace aidl {namespace android {namespace hardware {namespace invcase { class Invcase : public BnInvcase {    public:        //AIDL:String getChars();        ndk::ScopedAStatus getChars(std::string* _aidl_return);        //AIDL:void putChars(in String msg);        ndk::ScopedAStatus putChars(const std::string& in_msg);};} }  } } 2.AIDL对应Server端c++实现# emacs hardware/interfaces/invcase/aidl/default/Invcase.cpp#define LOG_TAG "Invcase" #include <utils/Log.h>#include <iostream>#include <fstream>#include "Invcase.h" namespace aidl {    namespace android {        namespace hardware {            namespace invcase {                //String getChars();                ndk::ScopedAStatus Invcase::getChars(__unused std::string* _aidl_return) {                    std::string str = "I am from HAL layer";                    *_aidl_return = str;                    ALOGE("%s, %s(), line = %d, HAL: send_to_app: %s",__FILE__,__FUNCTION__,__LINE__,str.c_str());                    return ndk::ScopedAStatus::ok();                }                //void putChars(in String msg);                ndk::ScopedAStatus Invcase::putChars(__unused const std::string& in_msg) {                    ALOGE("%s, %s(), line = %d, HAL: recive_from_app = %s",__FILE__,__FUNCTION__,__LINE__,in_msg.c_str());                    return ndk::ScopedAStatus::ok();                }            }         }     } } 在Invcase::getChars和Invcase::putChars函数中添加对驱动程序的访问即可。在这里我只是写了打印语句。到这里AIDL的Server端也实现完成,我们要将实现的内容注册成一个AIDL服务,可以通过Binder完成IPC通信。4.创建AIDL IPC通信1.注册AIDL服务# emacs hardware/interfaces/invcase/aidl/default/service.cpp#define LOG_TAG "Invcase"#include <android-base/logging.h>#include <android/binder_manager.h>#include <android/binder_process.h>#include <binder/ProcessState.h>#include <binder/IServiceManager.h>#include "Invcase.h"using aidl::android::hardware::invcase::Invcase;using std::string_literals::operator""s; int main() {    android::ProcessState::initWithDriver("/dev/vndbinder");     ABinderProcess_setThreadPoolMaxThreadCount(0);    ABinderProcess_startThreadPool();     std::shared_ptr<Invcase> invcase = ndk::SharedRefBase::make<Invcase>();    const std::string name = Invcase::descriptor + "/default"s;    ALOGE("%s, %s(), line = %d, descriptor = %s, name = %s,",__FILE__,__FUNCTION__,__LINE__,Invcase::descriptor,name.c_str());        if(AServiceManager_addService(invcase->asBinder().get(), name.c_str()) != STATUS_OK) {        ALOGE("Failed to register IInvcase service");        return -1;    }        ALOGE("IInvcase service starts to join s

中文

[翻译内容]