当前位置: 首页 > news >正文

Rk3588 Android12 AIDL 开发

AIDL (Android Interface Definition Language)HIDL (HAL Interface Definition Language) 都是 Android 系统中用于定义接口的工具,但它们有不同的用途和特性。

AIDL (Android Interface Definition Language)

  1. 用途

    • 主要用于应用程序之间的进程间通信 (IPC)。
    • 适用于定义应用程序组件(如 Activity 和 Service)之间的接口。

HIDL (HAL Interface Definition Language)

  1. 用途

    • 主要用于定义硬件抽象层 (HAL) 接口。
    • 适用于访问底层硬件功能,如摄像头、传感器等。

未来趋势

从 Android 13 开始,HIDL 已被弃用,建议使用 AIDL 来实现 HAL 接口⁴。这意味着未来的 Android 版本将更多地依赖 AIDL 来实现硬件抽象层的接口。

本文主要记录自己实现一个AIDL的过程

主要的架构逻辑

1.使能hidl-gen工具

source build/envsetup.sh
lunch rk3588_s-userdebug
make hidl-gen

2.建立自己的AIDL ,test目录 和ITest.hal,ITestWarpper.hal

1.mkdir vendor/rockchip/hardware/interfaces/test
2.mkdir vendor/rockchip/hardware/interfaces/test/1.03.新建ITest.hal文件
//vendor/rockchip/hardware/interfaces/test/1.0/ITest.hal
package rockchip.hardware.test@1.0;
import ITestWarpper;interface ITest
{setTestWarpper(ITestWarpper testWarpper);GetString()generates (string printString);
};4.新建ITestWarpper.hal文件 用于数据传递
//vendor/rockchip/hardware/interfaces/test/1.0/ITestWarpper.hal
package rockchip.hardware.test@1.0;
interface ITestWarpper
{GetString()generates (string printString);
};

生成编译文件vendor/rockchip/hardware/interfaces/test/1.0/Android.bp  

 do_makefiles_update rockchip.hardware:vendor/rockchip/hardware android.hardware:hardware/interfaces android.hidl:system/libhidl/transport

AIDL 的没有返回值都是VOID ,出参都是 generates (string printString);实现,类似C++的别名功能

生成对应的CPP和头文件

1.hidl-gen -o vendor/rockchip/hardware/test/1.0/defualt -Lc++-impl -rrockchip.hardware:vendor/rockchip/hardware -randroid.hidl:system/libhidl/transport rockchip.hardware  //生成C++ 和 H2.hidl-gen -o vendor/rockchip/hardware/test/1.0/defualt -Landroidbp-impl -rrockchip.hardware:vendor/rockchip/hardware/ -randroid.hidl:system/libhidl/transport rockchip.hardware  //生成Android.dp在defult 目录下生成对应的cpp文件和头文件,Android.bp

也可以使用我写的脚本生成对应的文件
./generate-source2.sh vendor/rockchip/hardware/interfaces/ test rockchip.hardware 

#! /bin/bash
# v1.0if [ -z $1 ]; thenecho "Please input path "exit 1
elseLOC=$1
fiif [ -z $2 ]; thenecho "Please input module name"exit 1
elseMODULE=$2
fiif [ -z $3 ]; thenecho "Please input package head"exit 1
elsePACKAGE_HEAD=$3
fiPACKAGE=$PACKAGE_HEAD.$MODULE@1.0
echo "You package is: $PACKAGE"hidl-gen -o $LOC/$MODULE/1.0/defualt -Lc++-impl -r$PACKAGE_HEAD:$LOC \-randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC/$MODULE/1.0/defualt -Landroidbp-impl -r$PACKAGE_HEAD:$LOC \-randroid.hidl:system/libhidl/transport $PACKAGE

修改Test.cpp Test.h

// FIXME: your file license if you have one#include "Test.h"
#include "log/log.h"
#define LOG_TAG "test1.0"
namespace rockchip::hardware::test::implementation {
sp<::rockchip::hardware::test::V1_0::ITestWarpper> mTestWarpper = nullptr;
hidl_string mDeviceId;
// Methods from ::rockchip::hardware::test::V1_0::ITest follow.
Return<void> Test::setTestWarpper(const sp<::rockchip::hardware::test::V1_0::ITestWarpper>& testWarpper) {// TODO implementmTestWarpper = testWarpper;return Void();
}Test::Test(){ALOGD("@%s.",__FUNCTION__);
}
Test::~Test(){ALOGD("@%s",__FUNCTION__);
}
V1_0::ITest* HIDL_FETCH_ITest(const char* /* name */) {ALOGD("@%s",__FUNCTION__);return new Test();
}
// [&](const ::android::hardware::hidl_string &id
Return<void> Test::GetString(GetString_cb _hidl_cb) {ALOGD("@%s,mDeviceId:%s",__FUNCTION__,mDeviceId.c_str());// TODO implementif(mTestWarpper!=nullptr){mTestWarpper->GetString([&](const ::android::hardware::hidl_string &id){ALOGD("@%s,GetString mDeviceId:%s",__FUNCTION__,id.c_str());_hidl_cb(id);});}return Void();
}// Methods from ::android::hidl::base::V1_0::IBase follow.//ITest* HIDL_FETCH_ITest(const char* /* name */) {//return new Test();
//}
//
}  // namespace rockchip::hardware::test::implementation
// FIXME: your file license if you have one#pragma once#include <rockchip/hardware/test/1.0/ITest.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>namespace rockchip::hardware::test::implementation {using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;struct Test : public V1_0::ITest {// Methods from ::rockchip::hardware::test::V1_0::ITest follow.Return<void> setTestWarpper(const sp<::rockchip::hardware::test::V1_0::ITestWarpper>& testWarpper) override;Return<void> GetString(GetString_cb _hidl_cb) override;Test();~Test();// Methods from ::android::hidl::base::V1_0::IBase follow.};// FIXME: most likely delete, this is only for passthrough implementations
extern "C" V1_0::ITest* HIDL_FETCH_ITest(const char* name);}  // namespace rockchip::hardware::test::implementation

添加一个开机服务 test/1.0/defualt下添加rc 和 xml文件和service.cpp

vendor/rockchip/hardware/interfaces/test/1.0/defualt/rockchip.hardware.test@1.0-service.rc
service test_server /vendor/bin/hw/rockchip.hardware.test@1.0-serviceclass haluser systemgroup systemvendor/rockchip/hardware/interfaces/test/1.0/defualt/rockchip.hardware.test@1.0-service.xml
<manifest version="1.0" type="device"><hal format="hidl"><name>rockchip.hardware.test</name><transport>hwbinder</transport><version>1.0</version><interface><name>ITest</name><instance>default</instance></interface></hal>
</manifest>vendor/rockchip/hardware/interfaces/test/1.0/defualt/service.cpp
#define LOG_TAG "rockchip.hardware.test@1.0-service"#include <rockchip/hardware/test/1.0/ITest.h>
#include <hidl/LegacySupport.h>
#include <binder/ProcessState.h>using rockchip::hardware::test::V1_0::ITest;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;int main() {android::ProcessState::initWithDriver("/dev/vndbinder");return defaultPassthroughServiceImplementation<ITest>("default", /*maxThreads*/ 6);
}

修改test/1.0/defualt/Android.dp

// FIXME: your file license if you have one
//生成一个AIDL so
cc_library_shared {// FIXME: this should only be -impl for a passthrough hal.// In most cases, to convert this to a binderized implementation, you should:// - change '-impl' to '-service' here and make it a cc_binary instead of a//   cc_library_shared.// - add a *.rc file for this module.// - delete HIDL_FETCH_I* functions.// - call configureRpcThreadpool and registerAsService on the instance.// You may also want to append '-impl/-service' with a specific identifier like// '-vendor' or '-<hardware identifier>' etc to distinguish it.name: "rockchip.hardware.test@1.0-impl",relative_install_path: "hw",// FIXME: this should be 'vendor: true' for modules that will eventually be// on AOSP.proprietary: true,srcs: ["Test.cpp","TestWarpper.cpp",],shared_libs: ["libhidlbase","libutils","liblog","rockchip.hardware.test@1.0",],
}
//生成一个服务进程cc_binary {name: "rockchip.hardware.test@1.0-service",init_rc: ["rockchip.hardware.test@1.0-service.rc"],vintf_fragments: ["rockchip.hardware.test@1.0-service.xml"],defaults: ["hidl_defaults"],proprietary: true,relative_install_path: "hw",srcs: ["service.cpp",],cflags: ["-Werror", "-Wno-unused-parameter"],shared_libs: ["liblog","libhardware","libhidlbase","libutils","libcutils","rockchip.hardware.test@1.0","libbinder","libhidlmemory",],
}
device 下根据自己的代码加入编译
PRODUCT_PACKAGES += \   rockchip.hardware.test@1.0-service \rockchip.hardware.test@1.0-impl

到这里我们的AIDL添加结束

二.修改系统te,不然服务跑不起来

添加文件device\rockchip\common\manifests\frameworks\rockchip.hardware.test@1.0-service.xml
<compatibility-matrix version="1.0" type="framework"><hal format="hidl" optional="true"><name>rockchip.hardware.test</name><version>1.0</version><interface><name>ITest</name><instance>default</instance></interface></hal>
</compatibility-matrix>添加文件device\rockchip\common\sepolicy\vendor\hal_test.te
type hal_test_default, domain;
type hal_test_default_exec, exec_type, vendor_file_type, file_type;init_daemon_domain(hal_test_default)allow hal_test_default device:dir { read open};
allow hal_test_default camera_device:chr_file{ read  write open ioctl };
allow hal_test_default vndbinder_device:chr_file { read write open ioctl map};
allow hal_test_default hidl_base_hwservice:hwservice_manager add;
allow hal_test_default hal_test_hwservice:hwservice_manager {add find};
allow system_app hal_test_hwservice:hwservice_manager { find };
binder_call(system_app, hal_test_default)
binder_call(hal_test_default, system_app)
#binder_call(hal_test_default, platform_app)
binder_call(hal_test_default, hwservicemanager)
#binder_call(hal_test_default, hal_camera_default)
# Client
#allow cameraserver hal_test_hwservice:hwservice_manager { find };
#allow hal_camera_default hal_test_hwservice:hwservice_manager { find };
get_prop(hal_test_default, hwservicemanager_prop)修改device\rockchip\common\sepolicy\vendor\hwservice_contexts
rockchip.hardware.tv.input::ITvInput                   u:object_r:hal_tv_input_hwservice:s0
+ rockchip.hardware.test::ITest                  u:object_r:hal_test_hwservice:s0修改device\rockchip\common\sepolicy\vendor\hwservice.te
+type hal_test_hwservice, hwservice_manager_type;

三。写一个测试demo

添加cpp和h 生成一个so 

//添加packages/apps/libtest_bridge/data_bridge.h
// #include <jni.h>
#include <functional>
#include <string>
#include <time.h>void init();
void deinit();//添加packages/apps/libtest_bridge/data_bridge.cpp
#define APK_VERSION	"V1.3"
#define LOG_TAG "test_bridge"
//#define LOG_NDEBUG 0#include <utils/Log.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utils/Log.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/v4l2-subdev.h>#include "data_bridge.h"#include <ui/Fence.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>#include <utils/Singleton.h>#define VIRTUAL_CAMERA
#define RGA_PROC #include <android/hardware_buffer_jni.h>
#include <vndk/hardware_buffer.h>#include <condition_variable>#ifdef RGA_PROC
#include <RockchipRga.h>
#include <im2d_api/im2d.h>
#include "im2d_api/im2d.hpp"
#include "im2d_api/im2d_common.h"
#endif#define LOGE(msg,...)   ALOGE("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)
#define LOGD(msg,...)   ALOGD("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)
#define LOGV(msg,...)   ALOGV("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)using namespace std;
using namespace android;
#include <rockchip/hardware/test/1.0/ITest.h>
class FrameWarpperImp :public rockchip::hardware::test::V1_0::ITestWarpper{public:android::hardware::Return<void> GetString(GetString_cb _hidl_cb) {// TODO implement::android::hardware::hidl_string deviceId = "hellow world";_hidl_cb(deviceId);return android::hardware::Void();}~FrameWarpperImp(){ALOGD("%s",__FUNCTION__);}FrameWarpperImp(){ALOGD("%s",__FUNCTION__);}
};
FrameWarpperImp *frameWarpperImp;
void init()
{::android::hardware::hidl_string testId;ALOGD("%s",__FUNCTION__);android::sp<rockchip::hardware::test::V1_0::ITest> client = rockchip::hardware::test::V1_0::ITest::getService();if(client.get()!= nullptr){        if (frameWarpperImp != nullptr){client->setTestWarpper(nullptr);frameWarpperImp = nullptr;}        frameWarpperImp = new FrameWarpperImp();ALOGD("setFrameDecorator");client->setTestWarpper(frameWarpperImp);client->GetString([&](const ::android::hardware::hidl_string &id){testId = id;ALOGD("setFrameDecorator%s",testId.c_str());});}
}
void deinit(){ALOGD("%s",__FUNCTION__);android::sp<rockchip::hardware::test::V1_0::ITest> client = rockchip::hardware::test::V1_0::ITest::getService();ALOGE("client.get():%p",client.get());if(client.get()!= nullptr){ALOGD("setFrameDecorator nullptr");client->setTestWarpper(nullptr);//delete frameWarpperImp ;frameWarpperImp = nullptr;}
}

packages/apps/libtest_bridge/Android.bp

//生成一个libtest_bridge.so
cc_library_shared {name: "libtest_bridge",srcs: ["data_bridge.cpp"],header_libs: ["jni_headers",],include_dirs: ["hardware/rockchip/librga",],shared_libs: ["libbase","libandroid","liblog","libutils","libcutils","libnativehelper","libhidlbase","libui","librga",
//rga_proc        "librga","rockchip.hardware.test@1.0",],cflags: ["-Wall","-Wno-error","-Wextra","-Wno-unused-parameter",],sanitize: {scs: true,},
}
ndk_library {name: "libtest_bridge",symbol_file: "libtest_bridge.map.txt",first_version: "30",
}
prebuilt_etc {name: "public.libtest_bridge",src: "public.libtest_bridge.txt",filename_from_src: true,
}//生成一个可执行文件test1.0_service
cc_binary {name: "test1.0_service",proprietary: true,relative_install_path: "hw",srcs: ["service.cpp",],defaults: ["hidl_defaults"],vendor: true,sdk_version: "current",cflags: ["-Wall","-Wno-error","-Wextra","-Wno-unused-parameter",],shared_libs: ["liblog","libtest_bridge",],
}

添加文件packages\apps\libtest_bridge\libtest_bridge.map.txt
LIBDATA_BRIDGE {global:init;local:*;
};添加文件packages\apps\libtest_bridge\public.libtest_bridge.txt
libtest_bridge.so nopreload添加文件packages\apps\libtest_bridge\service.cpp
#define LOG_TAG "rockchip.hardware.test@1.0-service"
#include "data_bridge.h"int main() {init();
}

编译完成后将系统的test1.0_service 推到 data/loal/tmp

执行./test1.0_service 

09-05 07:08:06.633  2892  2892 D data_bridge: init
09-05 07:08:06.634  2892  2892 D data_bridge: FrameWarpperImp
09-05 07:08:06.634  2892  2892 D data_bridge: setFrameDecorator
09-05 07:08:06.635   454   454 D test1.0 : @GetString,mDeviceId:
09-05 07:08:06.635   454   454 D test1.0 : @operator(),GetString mDeviceId:
09-05 07:08:06.636  2892  2892 D data_bridge: setFrameDecoratorhellow world

本文章只做自己学习记录

相关文章:

Rk3588 Android12 AIDL 开发

AIDL (Android Interface Definition Language) 和 HIDL (HAL Interface Definition Language) 都是 Android 系统中用于定义接口的工具&#xff0c;但它们有不同的用途和特性。 AIDL (Android Interface Definition Language) 用途&#xff1a; 主要用于应用程序之间的进程间…...

两个长整数字符串求和(不允许使用ES6+)

两个长整数字符串求和(不允许使用ES6), 面试手撸代码遇到到这个问题 1. 实现方式第一种 // 短整数字符串前边补 0; num需要补 0 的短整数字符串, len 长整数字符串的长度 function fillZero (num, len) {let str num.toString();if (str.length < len) {str 0.repeat(…...

11 Java 方法引用、异常处理、Java接口之函数式编程(接口知识补充Function<T,R>、BiFunction<T, U, R>和自定义泛型接口)

文章目录 前言一、Java接口之函数式编程 --- 接口知识补充1 Function<T,R>泛型接口2 BiFunction<T, U, R>泛型接口3 自定义泛型函数式编程接口4 使用lambda表达式、方法引用进行函数式编程二、方法引用1 方法引用初体验(以Array.sort()方法为例)(1)什么是方法引…...

深入探索 Go 语言的编译器与垃圾回收机制

Go 编译器 Go 编译器是通过 go 工具执行的&#xff0c;这个工具的功能不仅仅是生成可执行文件。你可以使用 go tool compile 命令来编译一个 Go 源文件。这个操作将生成一个目标文件&#xff0c;也就是 .o 后缀的文件。以下是在 macOS Mojave 系统上执行的命令和结果展示&…...

2024国赛数学建模-模拟火算法(MATLAB 实现)

模拟退火算法 1.1 算法原理 模拟退火算法的基本思想是从一给定解开始 ,从邻域 中随机产生另一个解 ,接受 Metropolis准则允许目标函数在 有限范围内变坏 ,它由一控制参数 t决定 ,其作用类似于物 理过程中的温度 T,对于控制参数的每一取值 ,算法持续进 行“产生 —判断 —接受…...

YOLOv8 只检测人 只画框不要标签

参考了这个&#xff1a;YOLOv8只检测人&#xff08;或其他一种或者多种类别&#xff09;_yolov8只检测指定类别-CSDN博客 1. 只检测人&#xff1a;predict的时候指定参数classes[0] 2. 只画框不要标签&#xff1a;plot的时候传入labelsFalse 3. 标签中去掉置信度&#xff1a…...

如何将网络安全防范游戏化

组织对威胁的准备和恢复能力跟不上网络犯罪分子的进步。 一些首席执行官仍然认为网络安全需要偶尔干预&#xff0c;而不是持续关注。 但对于许多公司来说&#xff0c;情况并非如此&#xff1b;网络威胁准备需要协调一致的培训工作&#xff0c;因此网络安全团队在攻击发生时已…...

Qt QGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小_图片查看

QtQGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小 头文件&#xff1a; #ifndef TIMGWIDGET_H #define TIMGWIDGET_H#include <QGraphicsItem> #include <QMainWindow> #include <QObject> #include <QWidget>// class TImgWidget : pu…...

Percona Toolkit 神器全攻略(复制类)

Percona Toolkit 神器全攻略&#xff08;复制类&#xff09; Percona Toolkit 神器全攻略系列共八篇&#xff0c;前文回顾&#xff1a; 前文回顾Percona Toolkit 神器全攻略Percona Toolkit 神器全攻略&#xff08;实用类&#xff09;Percona Toolkit 神器全攻略&#xff08;配…...

SQLite3 数据类型深入全面讲解

SQLite3&#xff0c;作为一款轻量级的数据库管理系统&#xff0c;在数据存储方面展现出了其独特的魅力。它不仅支持标准的SQL语法&#xff0c;还提供了丰富的数据类型供开发者选择。这些数据类型不仅涵盖了基本的数值和文本类型&#xff0c;还包括了日期时间、二进制数据等复杂…...

Python高效实现Trie(前缀树)及其插入和查找操作

Python高效实现Trie(前缀树)及其插入和查找操作 在Python面试中,考官通常会关注候选人的编程能力、问题解决能力以及对Python语言特性的理解。Trie(前缀树)是一种高效的数据结构,广泛应用于字符串处理、自动补全、拼写检查等场景。本文将详细介绍如何实现一个Trie,并提…...

傅里叶变换家族

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码...

深度学习——强化学习算法介绍

强化学习算法介绍 强化学习讨论的问题是一个智能体(agent) 怎么在一个复杂不确定的环境(environment)里面去极大化它能获得的奖励。 强化学习和监督学习 强化学习有这个试错探索(trial-and-error exploration)&#xff0c;它需要通过探索环境来获取对环境的理解。强化学习 ag…...

轴承知识大全,详细介绍(附3D图纸免费下载)

轴承一般由内圈、外圈、滚动体和保持架组成。对于密封轴承&#xff0c;再加上润滑剂和密封圈&#xff08;或防尘盖&#xff09;。这就是轴承的全部组成。 根据轴承使用的工作状况来选用不同类型的轴承&#xff0c;才能更好的发挥轴承的功能&#xff0c;并延长轴承的使用寿命。我…...

【PyTorch】基础环境如何打开

前期安装可以基于这个视频&#xff0c;本文是为了给自己存档如何打开pycharm和jupyter notebookPyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】_哔哩哔哩_bilibili Pycharm 配置 新建项目的时候选择解释器pytorch-gpu即可。 Jupyte…...

QT教程:QTime和QTimer的使用场景

QTime类 QTime 是一个用来表示和操作时间的类&#xff0c;它处理一天中的具体时间&#xff08;例如小时、分钟、秒、毫秒&#xff09;。通常用于计算时间间隔、记录时间戳、获取当前时间等。 特点和功能 表示时间&#xff1a;QTime 用来表示一天中的某个具体时间&#xff08;小…...

MySQL 迁移中 explicit_defaults_for_timestamp 参数影响

前言 最近在做数据迁移的时候&#xff0c;使用的是云平台自带的同步工具&#xff0c;在预检查阶段&#xff0c;当时报错 explicit_defaults_for_timestamp 参数在目标端为 off 建议修改 on&#xff0c;有什么风险呢&#xff1f;在此记录下。 测试对比 MySQL 默认情况下 expl…...

树状数组记录

树状数组&#xff08;Fenwick Tree&#xff09;是一种用于维护数组前缀和的数据结构&#xff0c;支持高效的单点更新和区间查询操作。它的查询和更新时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)&#xff0c;适用于需要频繁更新和查询的场景。 树状数组的基本操作 单点更…...

客户端时间和服务器时间的区别

客户端时间&#xff1a; 服务器向客户端拷贝一份前端内容&#xff0c;客户端通过JS获取时间&#xff0c;这样获取的是客户端时间 服务器时间&#xff1a; 服务器通过java代码获取的时间传输给客户端&#xff0c;这样获取的是服务器时间 当有些时候需要使用客户端时间&#xf…...

已入职华为!!关于我成功拿下华为大模型算法岗经验总结

方向:大模型算法工程师 整个面试持续了1小时10分钟&#xff0c;能够看出面试官是典型搞技术的&#xff0c;问的很专业又很细&#xff0c;全程感觉压力好大&#xff0c;面完后感觉丝丝凉意&#xff0c;不过幸好还是成功拿下了Offer 一面: 自我介绍 简历项目深度交流 1.项目的背…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...