尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【NDK / JNI】Sceneform-EQR 集成 Filament JNI 源码:关键点与逐步操作记录 - EQ

【NDK / JNI】Sceneform-EQR 集成 Filament JNI 源码:关键点与逐步操作记录 - EQ
📅 发布时间:2026/6/18 18:15:24

摘要:
在 Sceneform-EQR 项目中,原有对 Filament 的使用方式仅依赖官方预编译产物,Native 层不可控且 SO 体积较大。
为提升工程可维护性并优化产物体积,本文记录了在不修改 Filament Java API 的前提下,引入 Filament JNI 源码、合并 filament-android / filament-utils-android / gltfio-android 三个模块,并统一 JNI_OnLoad 的完整实践过程。

Sceneform-EQR 集成 Filament JNI 源码的工程优化实践

结论:从 Java-only 依赖到 Native 一体化编译,压缩 SO 体积 35%+
so库从4.3M压缩至2.8M

仓库地址:https://github.com/eqgis/Sceneform-EQR/tree/dev-withFilamentCpp

一、项目优化背景

1. Sceneform-EQR 与 Filament 的现状

Sceneform-EQR 本质上是一个基于 Filament 的 Android 3D / AR 渲染框架。
在现有工程结构中:

  • Java 层:直接依赖 Filament 官方提供的 Java API

  • Native 层:使用官方预编译好的 *.so / *.a 产物

  • Filament 模块拆分:

    • filament-android
    • filament-utils-android
    • gltfio-android

这种方式虽然接入成本低,但在实际工程中逐渐暴露出几个问题。


2. 原有方案的痛点

(1)SO 体积偏大

Filament 官方 Android 产物以模块级 so形式存在:

  • 多个 so 文件
  • 每个 so 内部存在一定符号冗余
  • 无法针对 Sceneform-EQR 的真实使用场景裁剪

最终 APK / AAR 体积不友好


(2)Native 层不可控

  • 无法修改 JNI 注册逻辑
  • 无法裁剪不需要的 Native 功能
  • 排查 Native Crash 时,只能“对着黑盒猜”

(3)后续深度定制受限

随着 Sceneform-EQR 后续规划:

  • 自定义渲染管线
  • 深度接入 glTF / IBL / 视频纹理
  • 可能修改 Filament JNI 行为

故:必须依赖 Native 源码


3. 优化目标

综合考虑,最终确定本次优化目标:

  1. 引入 Filament JNI 源码
  2. 将 filament / utils / gltfio 三个模块合并为一个 so
  3. 统一 JNI_OnLoad,消除多 so 冲突
  4. 在不修改 Java API 的前提下,完成底层重构
  5. 降低 SO 体积,提升工程可维护性

二、准备阶段

1. 准备 Filament 源码

从官方仓库获取 Filament 源码:


2. 获取 Android Native 编译产物

有两种方式:

  • 方式一:自行编译 Filament

参考filament源码工程的build.md,按步骤操作即可获取

  • 方式二:直接使用官方 Release

当前推荐方式二,直接下载官方 Release 中的 android-native 产物:

https://github.com/google/filament/releases

解压后结构如下:

  • include/ → Filament 头文件
  • lib/arm64-v8a/*.a → 静态库


三、代码合并过程

1. Java 层代码合并

(1)覆盖 Filament Java API

当前 Sceneform-EQR 未修改 Filament Java 源码,因此可以直接覆盖:

com.google.android.filament.android.*

⚠️ 后续 Sceneform-EQR 将会对 Java API 有定制,需通过 Git 进行差异合并。


(2)合并三个 Android 模块的 Java 源码

将以下模块中的 src/main/java 内容合并至 Sceneform-EQR:

  • filament-android
  • filament-utils-android
  • gltfio-android


2. JNI 源码合并

(1)拷贝 filament-android JNI 源码

filament-1.67.1/android/filament-android/src/main/cpp

拷贝至:

Sceneform-eqr/cpp/filament-android


(2)同样处理 gltfio / filament-utils



3. 拷贝 common 代码

Filament JNI 依赖 common 层工具类:


拷贝至工程中


4. 拷贝 libs 与 third_party

从 Filament 源码中拷贝 必要的依赖库:

实践建议: 只拷贝编译所需库,避免 third_party 全量引入


四、解决 JNI_OnLoad 冲突(核心问题)

1. 问题本质

官方 Filament:

  • filament-android.so
  • filament-utils.so
  • gltfio.so

!!!每个模块都有自己的 JNI_OnLoad!!!

而现在:

  • 需要 合并为一个 so
  • 只能存在一个 JNI_OnLoad

2. 解决思路

  • 各模块:

    • 移除 JNI_OnLoad
    • 提供 registerXXX() 方法
  • 核心 so:

    • 统一 JNI_OnLoad
    • 手动调用各模块注册函数

3. 修改 Filament.cpp

extern "C"
JNIEXPORT jint registerFilament(JavaVM* vm, void* reserved) {JNIEnv* env;if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {return -1;}::filament::VirtualMachineEnv::JNI_OnLoad(vm);return JNI_VERSION_1_6;
}

4. 修改 Utils.cpp(filament-utils)

extern "C"
JNIEXPORT jint registerUtils(JavaVM* vm, void*) {...env->RegisterNatives(...)return JNI_VERSION_1_6;
}

5. 重写统一 JNI_OnLoad

extern "C"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {registerFilament(vm, nullptr);registerUtils(vm, nullptr);return JNI_VERSION_1_6;
}

五、Native 编译配置

1. 引入 Filament 静态库

将 android-native 产物引入工程:



2. CMakeLists 配置

  • filament-android
    跳转至git查看:
    https://github.com/eqgis/Sceneform-EQR/blob/dev-withFilamentCpp/Eq-Renderer/Android/eq-renderer/src/main/cpp/filament-android/CMakeLists.txt
  • gltfio-android
    跳转至git查看:
    https://github.com/eqgis/Sceneform-EQR/blob/dev-withFilamentCpp/Eq-Renderer/Android/eq-renderer/src/main/cpp/gltfio-android/CMakeLists.txt
  • filament-utils-android
    跳转至git查看:
    https://github.com/eqgis/Sceneform-EQR/blob/dev-withFilamentCpp/Eq-Renderer/Android/eq-renderer/src/main/cpp/filament-utils/CMakeLists.txt

!!!关键点:!!!

  • 使用 STATIC IMPORTED
  • 显式指定 .a 路径
  • 严格控制 target_link_libraries 顺序

3. 主模块 whole-archive

target_link_libraries(eqr-core-Wl,--whole-archivefilament-jnifilament-utils-jnigltfio-jni-Wl,--no-whole-archive
)

否则部分 JNI 符号会被裁剪


4. 头文件缺失问题

Filament 1.67.1 中:

  • backend/private 未包含在 android-native

解决方案:

从 Filament 源码工程补拷头文件

补充说明:当前需采用ndk 27以上版本


六、编译结果与优化收益

1. 最终 AAR 产物


2. SO 体积对比

方案 SO 大小
原多 so 方案 4.3 MB
合并 JNI 源码后 2.8 MB
  • 合并编译前
  • 合并编译后

体积减少约 35%


七、小结

本次优化带来的收益

  • SO 体积显著下降
  • Native 层完全可控
  • JNI 注册逻辑清晰统一
  • 为 Sceneform-EQR 后续深度定制打下基础

缺点:Sceneform-EQR升级filament的工作量增大,故以此文备忘~


相关新闻

  • 防水丁基胶带大型厂家及定制生产厂家的选购指南
  • 防水胶带正规厂商、品牌商、生产企业的全面解读与南通众皓推荐
  • 探秘辉昂印刷厂的发展前景、技术实力

最新新闻

  • 汕尾足不出户卖黄金,正规回收流程详解 - 余生黄金回收
  • 人形机器人全身电子系统通信
  • Motorola DSP5685x平台TDC1驱动API深度解析与嵌入式音频开发实践
  • Tailwind CSS Signals与其他Tailwind插件对比分析:终极指南
  • 2026沈阳名表回收行情怎么算?9641笔本地成交数据讲清估价逻辑 - 奢品小当家
  • 2026 年南通角钢批发厂家实地测评,制造业采购干货分享 - LYL仔仔

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号