Files
Hippy/docs/development/native-integration.md
T
2025-12-12 18:58:11 +08:00

24 KiB
Raw Permalink Blame History

环境搭建

这篇教程,讲述了如何将 Hippy 集成到 Android、iOS、Ohos、Flutter、Web(同构) 等平台。


Android

注:以下文档都是假设您已经具备一定的 Android 开发经验。


前期准备

  • 已经安装了 JDK version>=1.7 并配置了环境变量
  • 已经安装 Android Studio 最新版本
  • 运行 Demo 工程前需要完成 NDK,CMAKE,gradle 与相关插件的安装

Demo 体验

若想快速体验,可以直接基于我们的 Android Demo 来开发

快速接入

  1. 创建一个 Android 工程

  2. Maven 集成

    • 查询 Maven Central Hippy 版本,其中 hippy-release 为 release 版本(不携带 inspector),hippy-debug 为 debug 版本

    • 配置 build.gradle

      下面引用Hippy最新版本号可在上述链接中查询

     // implementation 'com.tencent.hippy:hippy-debug:3.0.1'
     implementation 'com.tencent.hippy:hippy-release:3.0.1'
     implementation 'androidx.legacy:legacy-support-v4:1.0.0'
     implementation 'androidx.recyclerview:recyclerview:1.1.0'
     implementation 'androidx.viewpager:viewpager:1.0.0'
    
  3. 本地集成(可选)

    • hippy-framework 工程运行 Gradle Task other => assembleRelease 或者 other => assembleDebug 后会在 framework/android/build/outputs/aar 目录下生成 release 或者 debug 模式的android-sdk.aar,将 android-sdk.aar 拷贝到你项目的 libs 目录下。

      !> 通过 assembleRelease task 生成的 AAR 默认不携带 inspector 模块,不能在前端通过 Devtools 对代码进行调试,若需要集成 inspector,请执行 assembleDebug task

    • 配置 build.gradle

     api (name:'android-sdk', ext:'aar')
     implementation 'androidx.legacy:legacy-support-v4:1.0.0'
     implementation 'androidx.recyclerview:recyclerview:1.1.0'
     implementation 'androidx.viewpager:viewpager:1.0.0'
    
  4. 在宿主 APP 工程中增加引擎初始化与 hippyRootView 挂载逻辑,具体可以参考 Demo 工程中 HippyEngineWrapper 实现

iOS

注:以下文档都是假设您已经具备一定的 iOS 开发经验。

这篇教程,讲述了如何将 Hippy 集成到一个现有的 iOS 工程。


一、环境准备

  • 安装 Xcode

  • 安装 CMake

    推荐使用Homebrew安装CMake,安装命令如下:

    brew install cmake
    
  • 安装 CocoaPods

    CocoaPods 是一个iOS和macOS开发中流行的包管理工具。我们将使用它把Hippy的iOS Framework添加到现有iOS项目中。

    推荐使用Homebrew安装CocoaPods,安装命令如下:

    brew install cocoapods
    

若想快速体验,可以直接基于Hippy仓库中的 iOS Demo 来开发

二、使用 Cocoapods 集成 iOS SDK

具体的操作步骤如下:

  1. 首先,确定要集成的Hippy iOS SDK版本,如3.2.0,将其记录下来,接下来将在Podfile中用到。

    可到「版本查询地址」查询最新的版本信息

  2. 其次,准备好现有iOS工程的 Podfile 文件

    Podfile 文件是CocoaPods包管理工具的配置文件,如果当前工程还没有该文件,最简单的创建方式是通过CocoaPods init命令,在iOS工程文件目录下执行如下命令:

    pod init
    

    生成的Podfile将包含一些demo设置,您可以根据集成的目的对其进行调整。

    为了将Hippy SDK集成到工程,我们需要修改Podfile,将 hippy 添加到其中,并指定集成的版本。修改后的Podfile应该看起来像这样:

    #use_frameworks!
    platform :ios, '11.0'
    
    # TargetName大概率是您的项目名称
    target TargetName do
    
        # 在此指定步骤1中记录的hippy版本号,可访问 https://github.com/Tencent/Hippy/releases 查询更多版本信息
        pod 'hippy', '3.2.0'
    
    end
    

    默认配置下,Hippy SDK使用布局引擎是Taitank,JS引擎是系统的JavaScriptCore,如需切换使用其他引擎,请参照下文《引擎切换(可选)》一节调整配置。

    !> 请注意,由于hippy3.x中大量使用了 #include"path/to/file.h" 的方式引用C++头文件,因此如果开启了 CocoaPods 的 framework 格式集成选项(即Podfile中 use_frameworks! 配置为开启状态),则必须在 Podfile 文件中加入如下配置:

    # 工程开启 use_frameworks! 后需添加此环境变量,用于hippy使用正确设置项
    ENV["use_frameworks"] = "true"
    
  3. 最后,在命令行中执行

    pod install
    

    命令成功执行后,使用 CocoaPods 生成的 .xcworkspace 后缀名的工程文件来打开工程。

三、编写SDK接入代码,加载本地或远程的Hippy资源包

Hippy SDK的代码接入简单来说只需两步:

1、初始化一个HippyBridge实例,HippyBridge是Hippy最重要的概念,它是终端渲染侧与前端驱动侧进行通信的桥梁,同时也承载了Hippy应用的主要上下文信息。

2、通过HippyBridge实例初始化一个HippyRootView实例,HippyRootView是Hippy应用另一个重要概念,Hippy应用将由它显示出来,因此可以说创建业务也就是创建一个 HippyRootView。

目前,Hippy 提供了分包加载接口以及不分包加载接口,使用方式分别如下:

方式1. 使用分包加载接口

/** 此方法适用于以下场景:
 * 在业务还未启动时先准备好JS环境,并加载包1,当业务启动时加载包2,减少包加载时间
 * 我们建议包1作为基础包,与业务无关,只包含一些通用基础组件,所有业务通用
 * 包2作为业务代码加载
*/

// 先加载包1,创建出一个HippyBridge实例
// 假设commonBundlePath为包1的路径
// Tips:详细参数说明请查阅头文件: HippyBridge.h
NSURL *commonBundlePath = getCommonBundlePath();
HippyBridge *bridge = [[HippyBridge alloc] initWithDelegate:self
                                                  bundleURL:commonBundlePath
                                             moduleProvider:nil
                                              launchOptions:your_launchOptions
                                                executorKey:nil];

// 再通过上述bridge以及包2地址创建HippyRootView实例
// 假设businessBundlePath为包2的路径
// Tips:详细参数说明请查阅头文件: HippyRootView.h
HippyRootView *rootView = [[HippyRootView alloc] initWithBridge:bridge
                                                    businessURL:businessBundlePath
                                                     moduleName:@"Your_Hippy_App_Name"
                                              initialProperties:@{}
                                                   shareOptions:nil
                                                       delegate:nil];

// 最后,给生成的rootView设置好frame,并将其挂载到指定的VC上。
rootView.frame = self.view.bounds;
rootView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.view addSubview:rootView];

// 至此,您已经完成一个Hippy应用的初始化,SDK内部将自动加载资源并开始运行Hippy应用。

方式2. 使用不分包加载接口

// 与上述使用分包加载接口类似,首先需要创建一个HippyBridge实例,
// 区别是在创建HippyRootView实例时,无需再传入业务包,即businessBundlePath,直接使用如下接口创建即可
// Tips:详细参数说明请查阅头文件: HippyRootView.h
- (instancetype)initWithBridge:(HippyBridge *)bridge
                    moduleName:(NSString *)moduleName
             initialProperties:(nullable NSDictionary *)initialProperties
                  shareOptions:(nullable NSDictionary *)shareOptions
                      delegate:(nullable id<HippyRootViewDelegate>)delegate;

在Hippy仓库中提供了一个简易示例项目,包含上述全部接入代码,以及更多注意事项。

建议参考该示例完成SDK到已有项目的集成:iOS Demo,更多设置项及使用方式请查阅上述头文件中的具体API说明。

!> 使用分包加载可以结合一系列策略,比如提前预加载bridge, 全局单bridge等来优化页面打开速度。

到这里,您已经完成了接入一个默认配置下的Hippy iOS SDK的全部过程。

四、引擎切换(可选)

Hippy 3.x的一个重要特性是支持了多引擎的便捷切换,目前,可切换的引擎有两个,一是布局引擎,二是JS引擎。默认配置下,Hippy使用布局引擎是Taitank,JS引擎是iOS系统内置的JavaScriptCore。

如需使用其他布局引擎,如Yoga,或使用其他JS引擎,如V8,可参考如下指引调整Hippy接入配置。

Hippy3.x提供了iOS环境下默认的v8引擎实现,如需使用其他JS引擎需用户自行实现相关napi接口。

4.1 切换JS引擎

如需使用V8引擎,在Podfile文件中添加如下环境变量即可:

ENV['js_engine'] = 'v8'

修改后的Podfile应该看起来像这样:

#use_frameworks!
platform :ios, '11.0'
ENV['js_engine'] = 'v8' #切换为V8引擎

# TargetName大概率是您的项目名称
target TargetName do

    pod 'hippy', 'your_specified_version'

end

之后,重新执行pod install命令更新项目依赖即可。

如需使用其他第三方JS引擎,需要做如下操作:

1.修改Podfile配置为第三方JS引擎

将Podfile中的js_engine环境变量配置为other,这样在拉取代码时,jsc或者v8的代码将不会被添加到工程中。

ENV['js_engine'] = 'other'

Hippy3.0中使用napi抽象了不同JS引擎的接口。其中,JSC与V8的接口进行了实现。用户若使用JSC或者V8,可直接切换,Hippy默认进行了实现。

2.自行实现napi抽象接口

napi将js引擎接口抽象化,由js driver层调用。接入方自行实现napi接口,即可实现对第三方JS引擎的支持。

napi文件位于 /driver/js/napi* 目录下。

3.将实现文件添加到工程中

接入方自行将对应的napi实现文件添加到工程中。

4.2 切换布局引擎

用户若想使用Yoga布局引擎,直接在Podfile文件中指定layout_engine为Yoga即可:

ENV['layout_engine'] = 'Yoga'

之后,重新执行pod install命令更新项目依赖即可。

Ohos

注:以下文档都是假设您已经具备一定的 Ohos 开发经验。


前期准备

  • 已经安装 DevEco Studio 最新版本

Demo 体验

  • Ohos Har Demo:Har 包方式依赖 Hippy。 体验方法:DevEco 打开 hippy 项目根目录运行 entry_har。
  • Ohos Demo:源码依赖 Hippy。体验方法:DevEco 打开 hippy 项目根目录直接运行 entry。

注:一定是打开 Hippy 项目根目录,不是 Demo 的根目录

接入方式一:Har包快速接入

1. 创建一个 Ohos 工程

2. Har 包集成

  • 配置 oh-package.json5,依赖 Hippy har 包

依赖远程 ohpm 上 Har 包:

 "dependencies": {
   "hippy": "3.3.2"
 }

或者依赖本地 Har 包:

 "dependencies": {
   "hippy": "file:./libs/hippy.har"
 }
  • Hippy har包产物构建方法:
    • DevEco Studio 打开 Hippy 根目录
    • DevEco Studio 里 Build Mode 选择 release 或 debug
    • DevEco Studio 里选择 Hippy 模块下文件,比如选择 /framework/ohos/src/main/cpp/CMakeLists.txt
    • DevEco Studio 菜单里 Build - Make Module 'hippy'
    • 目录 /framework/ohos/build/default/outputs/default/ 里生成 hippy.har

3. 初始化代码

  • 获取 libhippy.so 接口对象和 UIAbility context

    import libHippy from 'libhippy.so' // libhippy.so下面可能会有红线提示,可忽略
    AppStorage.setOrCreate("libHippy", libHippy)
    AppStorage.setOrCreate("abilityContext", this.context)
    AppStorage.setOrCreate("mainWindow", mainWindow)
    

注:App 直接集成 Hippy,context 使用 UIAbility context;如果 App 在一个模块里集成 Hippy,js 等资源也集成在模块里,context 使用 getContext().createModuleContext("moduleName"),否则会找不到 js 等资源。

  • 创建 HippyEngine、初始化 HippyEngine、加载业务 bundle

    this.hippyEngine = createHippyEngine(params)
    this.hippyEngine.initEngine()
    this.hippyEngine?.loadModule()
    

注:loadModule 需要在 initEngine 成功后调用,即回调结果返回 EngineInitStatus.STATUS_OK 后

  • 组装 HippyRoot 组件
 HippyRoot({
     hippyEngine: this.hippyEngine,
     rootViewWrapper: this.rootViewWrapper,
     onRenderException: (exception: HippyException) => {
       this.exception = `${exception.message}\n${exception.stack}`
     },
 })

4. 销毁代码

Hippy页面退出时,需要释放资源。 destroyModule 用来释放对应 loadModule 的页面资源,destroyEngine 用来释放对应 initEngine 的引擎环境资源。 一定要先 destroyModule,返回后再 destroyEngine。

 hippyEngine?.destroyModule(rootId, () => {
   hippyEngine?.destroyEngine();
 });

注:确保这里 this.hippyEngine 和 this.rootViewWrapper 是有效值

具体可以参考 Har Demo 工程中 EntryAbility.ets Index.ets 实现

接入方式二:源码接入

源码接入主要为了方便在 App 项目里直接调试 Hippy 代码(c++ 和 ets 代码)。

1. 创建一个 Ohos 工程

2. Hippy 代码集成

  • 拉取 hippy 代码到项目里(比如:根目录下,IDE 限制 Hippy 源代码一定要在依赖 Hippy 的项目/模块的目录或子目录里,否则编译会报ets文件路径无法解决的错误)

https://github.com/Tencent/Hippy.git,分支:main

  • 配置 oh-package.json5,依赖 Hippy 文件目录
 "dependencies": {
    "hippy": "file:../Hippy/framework/ohos/"
 }

3. Hippy C++ 代码编译配置

  • 如果业务模块没有使用 C++,需 build-profile.json5 里配置使用,如下
 "externalNativeOptions": {
   "path": "./src/main/cpp/CMakeLists.txt",
   "arguments": "",
   "cppFlags": "",
 },
  • CMakeLists.txt 内容如下
cmake_minimum_required(VERSION 3.14)
project(hippy)

set(BIZ_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../")
set(HIPPY_ROOT_DIR "${BIZ_ROOT_DIR}/Hippy_src/framework/ohos/")
set(HIPPY_IMPL_CPP_DIR "${HIPPY_ROOT_DIR}/src/main/cpp/impl")

add_subdirectory("${HIPPY_IMPL_CPP_DIR}" ./hippy_impl)

add_library(${PROJECT_NAME} SHARED

)

target_link_libraries(${PROJECT_NAME} PUBLIC hippy_impl)

set(SOURCE_SET
 )
set(PUBLIC_SOURCE_SET
 )
target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_SET} PUBLIC ${PUBLIC_SOURCE_SET})

4. 初始化代码

  • 获取 libhippy.so 接口对象和 UIAbility context

    import libHippy from 'libhippy.so'
    AppStorage.setOrCreate("libHippy", libHippy)
    AppStorage.setOrCreate("abilityContext", this.context)
    AppStorage.setOrCreate("mainWindow", mainWindow)
    
  • 创建 HippyEngine、初始化 HippyEngine、加载业务 bundle

    this.hippyEngine = createHippyEngine(params)
    this.hippyEngine.initEngine()
    this.hippyEngine?.loadModule()
    
  • 组装 HippyRoot 组件

 HippyRoot({
     hippyEngine: this.hippyEngine,
     rootViewWrapper: this.rootViewWrapper,
     onRenderException: (exception: HippyException) => {
       this.exception = `${exception.message}\n${exception.stack}`
     },
 })

5. 销毁代码

Hippy页面退出时,需要释放资源。 destroyModule 用来释放对应 loadModule 的页面资源,destroyEngine 用来释放对应 initEngine 的引擎环境资源。 一定要先 destroyModule,返回后再 destroyEngine。

 hippyEngine?.destroyModule(rootId, () => {
   hippyEngine?.destroyEngine();
 });

具体可以参考 Demo 工程中 EntryAbility.ets 等实现

接入方式三:定制场景接入

  • 对于需要直接依赖 hippy c++ 代码编译使用的定制场景,可参考 Demo 工程中 CMakeLists.txt 说明

Voltron/Flutter

注:以下文档都是假设您已经具备一定的 Flutter 开发经验。

这篇教程,讲述了如何将 Hippy 集成到 Flutter 工程。


前期准备

  • 已经安装了 Flutter version>=3.0 并配置了环境变量

Demo 体验

若想快速体验,可以直接基于我们的 Voltron Demo 来开发,我们提供以下两种 Demo

  • 如果您的应用完全通过 Flutter 进行开发,可以参考flutter_proj,3.0正式发布前,请使用 flutter_proj

  • 如果您希望将 Voltron 集成进您的原生 IOS 或 Android 应用,可以使用 flutter module 进行集成

注意,使用 flutter_module 方式进行开发时,原生工程和 Flutter 工程在两个目录,上面所提到的 android-proj 和 IOSProj 均需要配合 flutter_module进行使用,3.0正式发布前,请使用 flutter_proj

快速接入

如果您的应用完全通过 Flutter 进行开发

  1. 创建一个 Flutter 工程

  2. Pub 集成

    在 pubspec.yaml 中添加 Voltron 依赖

    dependencies:
      voltron: ^0.0.1
    
  3. 本地集成(可选)

    1. 克隆 Hippy 源码

      git clone https://github.com/Tencent/Hippy.git
      

      注意使用相应的分支及tag,未合入主干前,请使用v3.0-dev分支

    2. 打开 Flutter 工程根目录下的 pubspec.yaml

      在 dependencies 下添加 voltron 依赖

      voltron:
        path: Hippy路径/framework/voltron
      
  4. 安装依赖

    flutter pub get
    
  5. 使用 Voltron

    建议参考flutter_proj,3.0正式发布前,请使用 flutter_proj

    Pub 集成方式在 Android 平台默认支持 arm64-v8a 和 armeabi-v7a,如需支持 x86 和 x86_64,请使用本地集成,iOS 无影响。

    需要注意,如果 debugMode 为YES的情况下,会忽略所有参数,直接使用 npm 本地服务加载测试 bundle,

如果您希望将 Voltron 集成进您的原生 IOS 或 Android 应用

  1. 使用该方式进行集成时,要首先集成 Flutter Module,该部分可直接参考官网Add Flutter to an existing app

  2. 后续流程与完全通过 Flutter 进行开发保持一致即可。也可直接参考我们的Demo工程

Web同构

这篇教程,讲述了如何将 Hippy 集成到 Web 页面中。

不同于 @hippy/react-web 和 @hippy/vue-web 方案,本方案(Web Renderer)不会替换 @hippy/react 和 @hippy/vue,而是将运行在原生环境下的 bundle 原封不动运行到 Web 上,与转译 Web 的方案各有利弊,业务可根据具体场景采用合适的方案


前期准备

  • 模板文件:Web 运行需要一个 HTML 文件作为入口
  • 入口文件:WebRenderer 是作为 Hippy bundle 的一个运行环境,因此不共享入口 JS 文件,应为其创建独立的入口文件

npm script

在 demo 项目中,通过 web:dev 命令启动 WebRenderer 调试服务,通过 web:build 打包编译。

  "scripts": {
    "web:dev": "npm run hippy:dev & node ./scripts/env-polyfill.js webpack serve --config ./scripts/hippy-webpack.web-renderer.dev.js",
    "web:build": "node ./scripts/env-polyfill.js
webpack --config ./scripts/hippy-webpack.web-renderer.js"
  }

启动调试

执行 npm run web:dev 启动 WebRenderer 调试,根据 demo 的 webpack 配置,WebRenderer 的 web 服务运行在3000端口,浏览器通过 http://localhost:3000 访问页面。

快速接入

WebRenderer 的执行应符合以下流程:

  1. 导入 WebRenderer:该阶段会初始化 Hippy 代码运行的环境
  2. 加载业务 bundle:这个 bundle 与 Native 侧运行的 bundle 包保持一致
  3. 启动 WebRenderer:该阶段会加载 Hippy 内置组件和模块,也可以加载自定义组件和模块

导入 WebRenderer

以 CDN 方式使用

在模板文件内添加:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <title>Example</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- web renderer cdn url -->
    <!-- Hippy不提供cdn资源管理,需业务自行上传之类 -->
    <script src="//xxx.com/lib/hippy-web-renderer/0.1.1/hippy-web-renderer.js"></script>
    <script src="src/index.ts"></script>
  </body>
</html>

以 NPM 包方式使用

npm install -S @hippy/web-renderer

在入口文件内添加:

// 1. 导入 web renderer
import { HippyWebEngine, HippyWebModule } from '@hippy/web-renderer';

// 2. 导入业务 bundle 的入口文件,需放在 web renderer 导入之后

// 3. 创建 web engine,如果有业务自定义模块和组件,从此处传入

加载业务 Bundle

加载 bundle 包有多种方式,可根据业务需要灵活选择,只需要确保引入顺序在 WebRenderer 之后即可

在模板文件内引用加载

<script src="//xxx.com/lib/hippy-web-renderer/0.1.1/hippy-web-renderer.js"></script>
<!-- 业务 bundle -->
<script src="//xxx.com/hippy-biz/index.bundle.js"></script>
<!-- 入口文件 -->
<script src="src/index.ts"></script>

在入口文件内动态加载

import { HippyWebEngine } from '@hippy/web-renderer';

const engine = HippyWebEngine.create();

 engine.load('https://xxxx.com/hippy-bundle/index.bundle.js').then(() => {
  engine.start({
    id: 'root',
    name: 'example',
  });
});

业务源码直接引用

import { HippyCallBack, HippyWebEngine, HippyWebModule, View } from '@hippy/web-renderer';
// 导入业务 bundle 的入口文件,需放在 web renderer 导入之后
import './main';


const engine = HippyWebEngine.create();

启动 WebRenderer

加载完业务 bundle 后,调用相关 API 创建并启动 WebRenderer

// 创建 web engine,如果有业务自定义模块和组件,从此处传入
// 如果只使用官方模块和组件,则直接使用 const engine = HippyWebEngine.create() 即可
const engine = HippyWebEngine.create({
  modules: {
    CustomCommonModule,
  },
  components: {
    CustomPageView,
  },
});

// 启动 web renderer
engine.start({
  // 挂载的 dom id
  id: 'root',
  // 模块名
  name: 'module-name',
  // 模块启动参数,业务自定义,
  // hippy-react 可以从 入口文件props里获取,hippy-vue可以从 app.$options.$superProps 里获取
  params: {
    path: '/home',
    singleModule: true,
    isSingleMode: true,
    business: '',
    data: { },
  },
});