RN 鸿蒙混合开发实践(踩坑)

#三方框架# #React Native #

1 。环境配置;

安装 DevEco 开发工具;

Node 版本16+;

hdc环境配置

hdc 是 OpenHarmony 为开发人员提供的用于调试的命令行工具,鸿蒙 React Native 工程使用 hdc 进行真机调试。hdc 工具通过 OpenHarmony SDK 获取,存放于 SDK 的 toolchains 目录下,请将 {DevEco Studio安装路径}/sdk/{SDK版本}/openharmony/toolchains 的完整路径添加到环境变量中。

安装 DevEco 的时候 勾选一下。就不用单独的添加环境变量了 。

配置 CAPI 版本环境变量

当前RN框架提供的 Demo 工程默认为 CAPI 版本,您需要配置环境变量 RNOH_C_API_ARCH = 1

  • Windows 环境:

    此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,在系统变量中点击新建,添加变量名为:RNOH_C_API_ARCH,变量值为 1

2,创建RN 工程

使用 React Native 内置的命令行工具来创建一个名为 “AwesomeProject” 的新项目。这个命令行工具不需要安装,可以直接用 node 自带的 npx 命令来创建,目前 React Native for OpenHarmony 仅支持 0.72.5 版本的 React Native:

npx react-native@0.72.5 init AwesomeProject --version 0.72.5

​该命令在 mac 环境下初始化 React Native 项目时会下载 iOS 依赖库,耗时较长,开发者可以选择执行以下命令跳过该过程,后续根据需要自行下载,不影响鸿蒙项目开发:

npx react-native@0.72.5 init AwesomeProject --version 0.72.5 --skip-install

安装鸿蒙化依赖

  1. 打开 AwesomeProject 目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:

    {"name": "AwesomeProject","version": "0.0.1","private": true,"scripts": {"android": "react-native run-android","ios": "react-native run-ios","lint": "eslint .","start": "react-native start","test": "jest",
    +    "dev": "react-native bundle-harmony --dev"},"dependencies": {"react": "18.2.0","react-native": "0.72.5"},"devDependencies": {"@babel/core": "^7.20.0","@babel/preset-env": "^7.20.0","@babel/runtime": "^7.20.0","@react-native/eslint-config": "^0.72.2","@react-native/metro-config": "^0.72.11","@tsconfig/react-native": "^3.0.0","@types/react": "^18.0.24","@types/react-test-renderer": "^18.0.0","babel-jest": "^29.2.1","eslint": "^8.19.0","jest": "^29.2.1","metro-react-native-babel-preset": "0.76.8","prettier": "^2.4.1","react-test-renderer": "18.2.0","typescript": "4.8.4"},"engines": {"node": ">=16"}
    }
    
  2. 在 AwesomeProject 目录下运行安装依赖包命令:

    npm i @react-native-oh/react-native-harmony@x.x.x
    

    注意:

    1. 指令中@x.x.x用于指定下载的版本,不指定时默认下载最新版本。
    2. 本地安装鸿蒙化依赖,请参考如何使用本地安装鸿蒙化依赖。
    3. 如何从本地依赖切换至远程依赖,请参考如何从本地依赖切换至远程依赖。

生成bundle

  1. 打开 AwsomeProject\metro.config.js,并添加 OpenHarmony 的适配代码。配置文件的详细介绍,可以参考React Native 中文网。修改完成后的文件内容如下:

    const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
    const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');/**
    * @type {import("metro-config").ConfigT}
    */
    const config = {transformer: {getTransformOptions: async () => ({transform: {experimentalImportSupport: false,inlineRequires: true,},}),},
    };module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
    }), config);
    
  2. 在 AwesomeProject 目录下运行生成 bundle 文件的命令。运行成功后,会在 AwesomeProject/harmony/entry/src/main/resources/rawfile 目录下生成 bundle.harmony.js 和 assets 文件夹,assets 用来存放图片(如果 bundle 中不涉及本地图片,则没有 assets 文件夹)。

    npm run dev
    

成功之后可以看到如下内容:

创建鸿蒙工程

本章节主要介绍了鸿蒙工程的创建,并加载 React Native 相关的依赖包和 bundle 包,最终完成鸿蒙工程的运行的过程。

您可以按照本节中的操作一步一步完成环境的搭建,也可以使用附件中的 MyApplicationReplace.zip 的内容,一一替换对应的文件,修改版本并运行。

新建工程或者在已有工程中集成

​ 下面演示在新建工程中集成。点击 File > New > Create Project,选择创建 Empty Ability 工程,如图所示:

​ 点击 Next 按钮,并在 Compile SDK 中选择 API13,(为了防止最新版本有各种问题)创建一个名为 “MyApplication” 的项目。注意项目路径不要太长,如图所示:

​ 连接真机,点击 File > Project Structure,在弹窗界面点击 Signing Configs,勾选 Support HarmonyOS 和 Automatically generate signature,然后点击 Sign In 登录华为账号,并签名。

添加 React Native 配置

在 entry 目录下执行以下命令:

ohpm i @rnoh/react-native-openharmony@x.x.x

执行完成后会在工程级目录以及模块级目录下生成 oh_modules 文件夹。

注意:

  1. 指令中@x.x.x用于指定下载的版本,不指定时默认下载最新版本。
  2. 由于 har 包比较大,这一步耗时会比较长,务必保证 ohpm install 和 IDE 自发的 SyncData 全都完成,否则会导致编译报错。
  3. 如何在三方库或自定义module中引入rnoh的依赖,请参考文档。

在原生工程中集成RNOH

补充CPP侧代码

  1. 在 MyApplication/entry/src/main 目录下新建 cpp 文件夹。
  2. 在 cpp 目录下新增 CMakeLists.txt,并将 RNOH 的适配层代码添加到编译构建中生成 librnoh_app.so
    project(rnapp)
    cmake_minimum_required(VERSION 3.4.1)
    set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
    set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
    set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
    set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
    set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
    add_compile_definitions(WITH_HITRACE_SYSTRACE)
    set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to useadd_subdirectory("${RNOH_CPP_DIR}" ./rn)add_library(rnoh_app SHARED"./PackageProvider.cpp""${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
    )target_link_libraries(rnoh_app PUBLIC rnoh)
    
  3. 在 cpp 目录下新增 PackageProvider.cpp,该文件需要满足以下要求:
    • 需要导入 RNOH/PackageProvider
    • 实现 getPackages 方法,用于创建三方库或自定义 TurboModule 或 Fabric 的 package 对象。

    此处不涉及三方库与自定义 TurboModule 或组件,需要返回空数组。

    #include "RNOH/PackageProvider.h"using namespace rnoh;std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {return {};
    }
    
  4. 打开 MyApplicaton\entry\build-profile.json5,将 cpp 中的代码添加到鸿蒙的编译构建任务中,详细介绍可以参考模块级build-profile.json5:
    {"apiType": "stageMode","buildOption": {
    +   "externalNativeOptions": {
    +      "path": "./src/main/cpp/CMakeLists.txt",
    +      "arguments": "",
    +      "cppFlags": "",
    +    }},"buildOptionSet": [{"name": "release","arkOptions": {"obfuscation": {"ruleOptions": {"enable": true,"files": ["./obfuscation-rules.txt"]}}}},],"targets": [{"name": "default"},{"name": "ohosTest",}]
    }
    

补充ArkTS侧的代码

  1. 打开 MyApplicaton\entry\src\main\ets\entryability\EntryAbility.ets,引入并使用 RNAbility,该文件需要满足以下的要求:
    • 如果需要扩展使用对应的生命周期函数,请在代码中使用 super,RNAbility 在生命周期函数中进行了对应的操作,需要使用 super 保证功能不丢失;
    • 需要重写 getPagePath,返回程序的入口 page。
    import { RNAbility } from '@rnoh/react-native-openharmony';export default class EntryAbility extends RNAbility {getPagePath() {return 'pages/Index';}
    }
    
  2. 在 MyApplicaton\entry\src\main\ets 目录下新增 RNPackagesFactory.ets,该文件需要满足以下要求:
    • 在 @rnoh/react-native-openharmony 导入 RNPackageContext 和 RNPackage
    • 在文件中导出 createRNPackages 方法,用于创建三方库或自定义 TurboModule、Fabric的package 对象。

    此处不涉及三方库与自定义TurboModule或组件,需要返回空数组。

    import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
    export function createRNPackages(ctx: RNPackageContext): RNPackage[] {return [];
    }
    
  3. 打开 MyApplicaton\entry\src\main\ets\pages\Index.ets,添加RNOH的使用代码,修改后如下:

    RNApp的参数appKey需要与RN工程中AppRegistry.registerComponent注册的appName保持一致,否则会导致白屏。

    import {AnyJSBundleProvider,ComponentBuilderContext,FileJSBundleProvider,MetroJSBundleProvider,ResourceJSBundleProvider,RNApp,RNOHErrorDialog,RNOHLogger,TraceJSBundleProviderDecorator,RNOHCoreContext
    } from '@rnoh/react-native-openharmony';
    import { createRNPackages } from '../RNPackagesFactory';@Builder
    export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)@Entry
    @Component
    struct Index {@StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined@State shouldShow: boolean = falseprivate logger!: RNOHLoggeraboutToAppear() {this.logger = this.rnohCoreContext!.logger.clone("Index")const stopTracing = this.logger.clone("aboutToAppear").startTracing();this.shouldShow = truestopTracing();}onBackPress(): boolean | undefined {// NOTE: this is required since `Ability`'s `onBackPressed` function always// terminates or puts the app in the background, but we want Ark to ignore it completely// when handled by RNthis.rnohCoreContext!.dispatchBackPress()return true}build() {Column() {if (this.rnohCoreContext && this.shouldShow) {if (this.rnohCoreContext?.isDebugModeEnabled) {RNOHErrorDialog({ ctx: this.rnohCoreContext })}RNApp({rnInstanceConfig: {createRNPackages,enableNDKTextMeasuring: true, // 该项必须为true,用于开启NDK文本测算enableBackgroundExecutor: false,enableCAPIArchitecture: true, // 该项必须为true,用于开启CAPIarkTsComponentNames: []},initialProps: { "foo": "bar" } as Record<string, string>,appKey: "AwesomeProject",wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,onSetUp: (rnInstance) => {rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")},jsBundleProvider: new TraceJSBundleProviderDecorator(new AnyJSBundleProvider([new MetroJSBundleProvider(),// NOTE: to load the bundle from file, place it in// `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`// on your device. The path mismatch is due to app sandboxing on OpenHarmonynew FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')]),this.rnohCoreContext.logger),})}}.height('100%').width('100%')}
    }
    

加载bundle包

​ 在上一章节中已经完成了 bundle 文件的生成,接下来将它加载到 DevEco Studio 中以运行 MyApplication 项目。加载 bundle 有三种方式:

  • 方式一:本地加载 bundle。将 bundle 文件和 assets 图片放在 entry/src/main/resources/rawfile 路径下,在 entry/src/main/ets/pages/Index.ets 中使用。

官方文档写了3种方式。我用的第一种!

全量编译 C++ 代码耗时较长,请耐心等待。

报错:

由于cpp 目录错误导致。

"externalNativeOptions": {"path": "./src/main/cpp/CMakeLists.txt","arguments": "","cppFlags": "","abiFilters": ["x86_64","arm64-v8a"]}

运行出错:

Error message:Couldn't create bindings between ETS and CPP. libRNOHApp is undefined.
Stacktrace:
SourceMap is not initialized yet
at RNOHError (entry|@rnoh/react-native-openharmony|0.72.27|src/main/ets/RNOH/RNOHError.ts:16:9)
at FatalRNOHError (entry|@rnoh/react-native-openharmony|0.72.27|src/main/ets/RNOH/RNOHError.ts:1:1)
at onInit (entry|@rnoh/react-native-openharmony|0.72.27|src/main/ets/RNOH/NapiBridge.js:12:25)
at create (entry|@rnoh/react-native-openharmony|0.72.27|src/main/ets/RNOH/RNInstancesCoordinator.ts:63:36)
at onCreate (entry|@rnoh/react-native-openharmony|0.72.27|src/main/ets/RNOH/RNAbility.ts:64:39)

始终没有解决 。

最后降低了 @rnoh/react-native-openharmony": 本版。

从 @rnoh/react-native-openharmony@0.72.67 到 @rnoh/react-native-openharmony": "0.72.38"

最终运行通过。

release包使用

  1. 在 MyApplication 目录下新建 libs 文件夹,将 react_native_openharmony-xxx-release.har 放入该目录。

  2. 打开 MyApplication/entry 下的 oh-package.json5,替换 har 包的依赖为对应版本的 release 包:

    {"name": "entry","version": "1.0.0","description": "Please describe the basic information.","main": "","author": "","license": "","dependencies": {
    +     "@rnoh/react-native-openharmony": "file:../libs/react_native_openharmony-xxx-release.har"}
    }
    
  3. 替换 MyApplication\entry\src\main\cpp\CMakeLists.txt 文件为以下代码:

    project(rnapp)
    cmake_minimum_required(VERSION 3.4.1)
    set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(NATIVERENDER_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
    set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
    set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/include")
    set(REACT_COMMON_PATCH_DIR "${RNOH_CPP_DIR}/patches/react_native_core")set(CMAKE_CXX_STANDARD 17)
    set(LOG_VERBOSITY_LEVEL 1)
    set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
    set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
    set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie -DNDEBUG")
    set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
    add_compile_definitions(WITH_HITRACE_SYSTRACE)
    # folly的编译选项
    set(folly_compile_options-DFOLLY_NO_CONFIG=1-DFOLLY_MOBILE=1-DFOLLY_USE_LIBCPP=1-DFOLLY_HAVE_RECVMMSG=1-DFOLLY_HAVE_PTHREAD=1-Wno-comma-Wno-shorten-64-to-32-Wno-documentation-faligned-new
    )
    add_compile_options("-Wno-unused-command-line-argument")
    # 添加头文件目录
    include_directories(${NATIVERENDER_ROOT_PATH}${RNOH_CPP_DIR}${REACT_COMMON_PATCH_DIR}${RNOH_CPP_DIR}/third-party/folly${RNOH_CPP_DIR}/third-party/rn/ReactCommon${RNOH_CPP_DIR}/third-party/rn/ReactCommon/react/nativemodule/core${RNOH_CPP_DIR}/third-party/rn/ReactCommon/jsi${RNOH_CPP_DIR}/third-party/rn/ReactCommon/callinvoker${RNOH_CPP_DIR}/third-party/boost/libs/utility/include${RNOH_CPP_DIR}/third-party/boost/libs/stacktrace/include${RNOH_CPP_DIR}/third-party/boost/libs/predef/include${RNOH_CPP_DIR}/third-party/boost/libs/array/include${RNOH_CPP_DIR}/third-party/boost/libs/throw_exception/include${RNOH_CPP_DIR}/third-party/boost/libs/config/include${RNOH_CPP_DIR}/third-party/boost/libs/core/include${RNOH_CPP_DIR}/third-party/boost/libs/preprocessor/include${RNOH_CPP_DIR}/third-party/double-conversion${RNOH_CPP_DIR}/third-party/rn/ReactCommon/react/renderer/graphics/platform/cxx${RNOH_CPP_DIR}/third-party/rn/ReactCommon/runtimeexecutor${RNOH_CPP_DIR}/third-party/glog/src${RNOH_CPP_DIR}/third-party/boost/libs/mpl/include${RNOH_CPP_DIR}/third-party/boost/libs/type_traits/include${RNOH_CPP_DIR}/third-party/rn/ReactCommon/yoga${RNOH_CPP_DIR}/third-party/boost/libs/intrusive/include${RNOH_CPP_DIR}/third-party/boost/libs/assert/include${RNOH_CPP_DIR}/third-party/boost/libs/move/include${RNOH_CPP_DIR}/third-party/boost/libs/static_assert/include${RNOH_CPP_DIR}/third-party/boost/libs/container_hash/include${RNOH_CPP_DIR}/third-party/boost/libs/describe/include${RNOH_CPP_DIR}/third-party/boost/libs/mp11/include${RNOH_CPP_DIR}/third-party/boost/libs/iterator/include${RNOH_CPP_DIR}/third-party/boost/libs/detail/include${RNOH_CPP_DIR}/patches/react_native_core/react/renderer/textlayoutmanager/platform/harmony)configure_file(${RNOH_CPP_DIR}/third-party/folly/CMake/folly-config.h.cmake${RNOH_CPP_DIR}/third-party/folly/folly/folly-config.h
    )
    file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
    # 添加rnoh动态共享包
    add_library(rnoh SHARED"${RNOH_CPP_DIR}/RNOHOther.cpp""${RNOH_CPP_DIR}/third-party/folly/folly/lang/SafeAssert.cpp")
    # 链接其他so
    target_link_directories(rnoh PUBLIC ${OH_MODULE_DIR}/@rnoh/react-native-openharmony/libs/arm64-v8a)
    target_link_libraries(rnoh PUBLICrnoh_semilibace_napi.z.solibace_ndk.z.solibrawfile.z.solibhilog_ndk.z.solibnative_vsync.solibnative_drawing.solibc++_shared.solibhitrace_ndk.z.soreact_render_schedulerrrc_imagerrc_textrrc_textinputrrc_scrollviewreact_nativemodule_corereact_render_animationsjsinspectorhermesjsiloggerreact_configreact_debugreact_render_attributedstringreact_render_componentregistryreact_render_corereact_render_debugreact_render_graphicsreact_render_imagemanagerreact_render_mapbufferreact_render_mountingreact_render_templateprocessorreact_render_textlayoutmanagerreact_render_telemetryreact_render_uimanagerreact_utilsrrc_rootrrc_viewreact_render_leakcheckerreact_render_runtimeschedulerruntimeexecutor)if("$ENV{RNOH_C_API_ARCH}" STREQUAL "1")message("Experimental C-API architecture enabled")target_link_libraries(rnoh PUBLIC libqos.so)target_compile_definitions(rnoh PUBLIC C_API_ARCH)
    endif()
    # RNOH_END: add_package_subdirectories# 添加rnoh_app共享包
    add_library(rnoh_app SHARED${GENERATED_CPP_FILES}"./PackageProvider.cpp""${RNOH_CPP_DIR}/RNOHOther.cpp""${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
    )target_link_libraries(rnoh_app PUBLIC rnoh)target_compile_options(rnoh_app PUBLIC ${folly_compile_options} -DRAW_PROPS_ENABLED -std=c++17)
    
  4. 将 MyApplication/entry 的 oh_modules 文件夹删除,点击 entry 文件夹,再点击顶部菜单栏的 build>Clean Project 清除项目缓存。

  5. 点击顶部菜单栏的 File > Sync and Refresh Project 来执行 ohpm install,执行完成后会在 entry 目录下生成 oh_modules 文件夹。

  6. 点击顶部菜单栏的 Run>Run 'entry' 运行工程 。

运行结果:

  • 打包 release的时候 ,har中没有 x86_64 。所以最终会运行失败。 有真机的小伙伴可以测试下。

完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态网站 LNMP

一、名词解释&#xff1a; LNMP&#xff1a; L : 代表 Linux 操作系统&#xff0c;为网站提供了可靠的运行环境N : 代表 Nginx&#xff0c;它是一款轻量级的高性能 Web 服务器&#xff0c;能够快速处理大量并 发连接&#xff0c;有效提升网站的访问速度和性能 M : 代表…

DAY04:Vue.js 指令与事件处理深度解析之从基础到实战

1. 指令系统核心概念 1.1 插值表达式与基础指令 Vue.js 的指令系统是其响应式编程模型的核心&#xff0c;我们首先从最基础的插值表达式开始&#xff1a; <div id"app"><!-- 基础文本插值 --><p>{{ message }}</p><!-- JavaScript 表达…

12配置Hadoop集群-集群配置

&#xff08;一&#xff09;Hadoop的组成 对普通用户来说&#xff0c; Hadoop就是一个东西&#xff0c;一个整体&#xff0c;它能给我们提供无限的磁盘用来保存文件&#xff0c;可以使用提供强大的计算能力。 在Hadoop3.X中&#xff0c;hadoop一共有三个组成部…

Kubernetes生产实战(四):kubelet日志快速定位指南

kubelet作为Kubernetes节点的核心管家&#xff0c;其日志是排查节点问题的金钥匙。本文将分享生产环境中查看和分析kubelet日志的完整方案&#xff0c;助你快速定位节点级故障。 一、基础操作&#xff1a;快速查看日志 1. systemd服务日志&#xff08;推荐首选&#xff09; …

麦科信获评CIAS2025金翎奖【半导体制造与封测领域优质供应商】

在苏州举办的2025CIAS动力能源与半导体创新发展大会上&#xff0c;深圳麦科信科技有限公司凭借在测试测量领域的技术积累&#xff0c;入选半导体制造与封测领域优质供应商榜单。本届大会以"新能源芯时代"为主题&#xff0c;汇集了来自功率半导体、第三代材料应用等领…

Python实例题:pygame开发打飞机游戏

目录 Python实例题 题目 pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本 代码解释 初始化部分&#xff1a; 游戏主循环&#xff1a; 退出部分&#xff1a; 运行思路 注意事项 Python实例题 题目 pygame开发打飞机游戏 pygame-aircraft-game使用 Pygame 开发…

Gin 框架入门

Gin 框架入门 一、响应数据 JSON 响应 在 Web 开发中&#xff0c;JSON 是一种常用的数据交换格式。Gin 提供了简便的方法来响应 JSON 数据。 package mainimport ("github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/json", func(c *…

Flink实时数仓数据突变时,如何快速排查原因

在大数据时代,数据的价值已经被无数企业和组织深刻认识到,而实时数仓作为数据处理和分析的重要基础设施,正在逐渐成为推动业务增长和决策优化的核心引擎。想象一下,电商平台在双十一大促期间需要实时监控订单量、用户行为,甚至库存变化,以便及时调整营销策略和物流调度;…

视频人像抠图技术选型--截止2025年4月

前言&#xff1a;我是一名算法工程师&#xff0c;经常需要对某个AI功能做技术调研和输出技术选型报告&#xff0c;在过去多年的工作当中&#xff0c;积累了很多内容&#xff0c;我会陆陆续续将这些内容整理出来分享给大家&#xff0c;希望大家喜欢&#xff0c;感谢您的阅读&…

docker compose ps 命令

docker compose ps 命令用于列出与 Docker Compose 项目相关的容器及其状态。 docker compose ps 能显示当前项目中所有服务容器的运行状态、端口映射等信息。 语法 docker compose ps [OPTIONS] [SERVICE…] SERVICE&#xff08;可选&#xff09;&#xff1a;指定要查看状态…

C语言 字符函数和字符串函数(1)

目录 1.字符分类函数 2.字符转换函数 3.strlen的使用和模拟实现 4.strcpy的使用和模拟实现 在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了方便操作字符和字符串&#xff0c;C语言标准库中提 供了一系列库函数&#xff0c;接下来我们就学习一下这…

MySQL 中如何进行 SQL 调优?

在MySQL中进行SQL调优是一个系统性工程&#xff0c;需结合索引优化、查询改写、性能分析工具、数据库设计及硬件配置等多方面策略。以下是具体优化方法及案例说明&#xff1a; 一、索引优化&#xff1a;精准提速的关键 索引类型选择 普通索引&#xff1a;加速频繁查询的列&…

OpenCV图像金字塔详解:原理、实现与应用

一、什么是图像金字塔&#xff1f; 图像金字塔是图像处理中一种重要的多尺度表示方法&#xff0c;它通过对图像进行重复的平滑和降采样&#xff08;或上采样&#xff09;操作&#xff0c;生成一系列分辨率逐渐降低&#xff08;或升高&#xff09;的图像集合。这种结构形似金字…

收集飞花令碎片——C语言分支与循环语句(上)

前言 Hello,各位码友&#xff0c;本章将会给大家带来C语言的分支与循环整章串讲&#xff0c;这一张的内容分为基础知识和程序练习两个部分 希望通过这一章能够带大家更好地去掌握C语言的分支与循环语句 大家一起努力吧 C语言分支与循环语句&#xff08;基础知识&#xff09; C…

嵌入式硬件篇---TOF|PID

文章目录 前言1. 硬件准备主控芯片ToF模块1.VL53L0X2.TFmini 执行机构&#xff1a;电机舵机其他 2. 硬件连接(1) VL53L0X&#xff08;IC接口&#xff09;(2) TFmini&#xff08;串口通信&#xff09; 3. ToF模块初始化与数据读取(1) VL53L0X&#xff08;基于HAL库&#xff09;(…

PCB设计实践(十二)PCB设计电容选型:功能、材质、规则

在PCB设计中&#xff0c;电容作为基础元件承担着滤波、储能、去耦、耦合等核心功能。其分类与使用规则直接影响电路稳定性、抗干扰能力和信号完整性。本文从工程实践角度系统梳理PCB设计中电容的五大分类、选型规范及布局布线规则&#xff0c;帮助设计者构建科学的电容应用体系…

vue2关闭eslint

在项目根目录下找到 vue.config.js 文件。如果没有该文件&#xff0c;可以直接在项目根目录创建一个。 2. 添加 lintOnSave: false 配置 module.exports {lintOnSave: false };

MyBatis 一对多关联映射在Spring Boot中的XML配置

在Spring Boot中使用MyBatis实现一对多关系时&#xff0c;可以通过XML映射文件来配置。下面我将详细介绍几种实现方式。 基本概念 一对多关系指的是一个实体对象包含多个子对象集合的情况&#xff0c;例如&#xff1a; 一个部门有多个员工一个订单有多个订单项一个博客有多个…

基于Stable Diffusion XL模型进行文本生成图像的训练

基于Stable Diffusion XL模型进行文本生成图像的训练 flyfish export MODEL_NAME"stabilityai/stable-diffusion-xl-base-1.0" export VAE_NAME"madebyollin/sdxl-vae-fp16-fix" export DATASET_NAME"lambdalabs/naruto-blip-captions"acceler…

基于React的高德地图api教程001:初始化地图

文章目录 1、初始化地图1.1 创建react项目1.2 可视化地图1.3 设置卫星地图1.4 添加开关开启3D地图1.5 代码下载1、初始化地图 1.1 创建react项目 创建geodeapi项目: npx create-react-app gaodeapi安装高德地图包: npm install @amap/amap-jsapi-loader1.2 可视化地图 在…