调查可行的选择
[注意此答案包含原始问题中的发现]
我对各种选择进行了更多的调查,以下是一些初步发现。
0. 编译 NodeJS
每个选项都使用为Android编译的某种形式的NodeJS。但是要使用任何选项,您可能希望编译为不同的Node,Android和架构(x86,ARM,ARM64等)版本。
这是有问题的。NodeJS有一个脚本,但这会导致我尝试过的大多数组合中的错误。我为一个工作构建脚本创建了许多github问题。在本期中,将收集以下结果:android-configure
总结一下:
- 共享库构建都失败(除非在Android上进行物理构建,见下文)
- 带有 NodeJS () 的 J2V8 在 7.x 至
libnode.a
libj2v8.so
7.9.0
- build-as-node-executable 适用于 7.x(使用 dna2oslab 构建脚本)
@mafintosh使用了一个有趣的解决方法:使用Termux将Node传输到设备并在那里进行编译(需要很多空间和时间,但有效)。
1. 运行包含 NodeJS (J2V8) 的 V8 javascript 引擎)
J2V8 是 V8 的一组 Java 绑定。J2V8 专注于性能和与 V8 的紧密集成。[...][这]在JS和Java代码之间强制使用更静态的类型系统,但它也提高了性能,因为中间对象不是创建的。[...]
构建 J2V8 需要同时构建本机部分和 Java 库(.jar/.aar 文件)。为了构建原生部分,我们首先构建node.js作为一个库,然后静态地将J2V8链接到它。[...]
对于交叉编译,J2V8使用Docker(android,linux,windows)和Vagrant(macos)。
参见 slideshare: Running NodeJS in a Java World(或參閱 InfoQ 視頻,32 分鐘)
产品特点:
- 用更强大的 v8 替换 JavaScriptCore 引擎(使用 NodeJS)
- 通过添加 J2V8 JNI / Java 层支持多线程(线程/工作线程)
- 双向 js 到 java 桥接(从脚本调用 java,反之亦然)
- 双向集成错误/异常处理
- 漂亮的交叉编译交互式构建系统(正在开发中))
- 部件版式调试支持
- 其他, 类型化数组, ES6 支持, ...
特点:
- 指定要在其中编译的版本
build_system/build_settings.py
-
只需使用 开始构建,选择 build:python build.py --interactive
[0] Docker >> android-x86 >> NODE_ENABLED
[1] Docker >> android-arm >> NODE_ENABLED
[2] Docker >> alpine-linux-x64 >> NODE_ENABLED
[3] Docker >> linux-x64 >> NODE_ENABLED
[4] Docker >> linux-x86 >> NODE_ENABLED
[5] Vagrant >> macosx-x64 >> NODE_ENABLED
[6] Vagrant >> macosx-x86 >> NODE_ENABLED
[7] Native >> windows-x64 >> NODE_ENABLED
[8] Docker >> windows-x64 >> NODE_ENABLED
[9] Vagrant >> windows-x64 >> NODE_ENABLED
-
选择构建步骤(或):all
NodeJS --> CMake --> JNI --> Optimize --> Java/Android --> JUnit
-
将 V8 编译为共享库libj2v8_{platform}_{abi}.{ext}
-
注意:构建步骤无法构建 Node 共享库(错误),创建静态以链接
nodejs
libnode.a
libj2v8.so
- 具有 JNI 层,使 Java 可以访问 v8 的大部分内容
- 在Java中实现的其他功能(例如.JS <-->Java桥接器)
- 最终构建输出是一个 Gradle,可作为项目依赖项包含在内
.aar
优点:
- 相对活跃的项目
- 高质量的代码,包括Java单元测试
- 将 Java 的全部功能添加到您的应用设计工具包中
- 出色、直观的构建系统(一旦完成)
缺点:
- 很少,大部分过时的使用文档
- 必须维护的大量 JNI 胶水代码
- 项目维护得不好(许多旧的未决问题,未合并的PR)
- 与其他选项相比,更难理解 J2V8 项目设置(许多文件)
-
许可问题(EPL 1.0 许可证中的“保留所有权利”)
Android上的Node的工作原理是使用共享库在Android应用程序内运行Node.js。然后,它会捆绑一个托管 UI 代码的。所有的UI都只是经典的html/css/js。WebView
在节点应用程序中,您可能需要访问 WebView。您可以使用它来加载 中的 html 页面。node-on-android
WebView
根据创建者(@mafintosh)的说法,这比J2V8更容易,更好,因为它直接将V8编译为真实的东西。node-on-android
产品特点:
- 构建成熟的NodeJS应用程序,包括UI(通过本机WebView)
特点:
- gradle项目中的相关目录/文件:
app
-
app/src/main/include/node
使用节点头.h
-
app/src/main/jniLibs/arm64-v8a
与 和libc++_shared.so
libnode.so
-
app/src/main/cpp
与 (包括native-lib.cpp
node.h
)
- Java代码,只是启动一个在单独的线程中运行的节点
Service
- 没有 的 JNI,因此在 IDE 中显示为错误(但编译)
libnode.so
private native void startNode(String... app);
- NodeJS 项目驻留在
android/app/src/main/assets/node
- NodeJS代码被传输到临时存储并从那里执行
- NodeJS应用程序指定通过公开的函数在WebView中加载的视图
loadUrl
- 可通过 NPM 包访问的节点服务
node-on-android
优点:
- 项目简单,管道代码不多
- 附带最新的 v8.x 节点版本,开箱即用
- 基于 HTML 的简单应用程序 UI 编程(例如,使用 choo)
- 开箱即用:)
缺点:
- 非常新的项目,只有实验代码
- 仅用于架构(计划提供完整的移动支持或DIY构建)
arm64
- 没有原生UI可能(除非用Gradle /Java/ XML编码)
- 在Node应用程序上没有调试支持(AFAIK,但也许你可以以某种方式附加到WebView)
3. 将 React Native 与 NodeJS app-as-a-service (react-native-node)相结合)
在后台运行一个真正的 Node.js进程,在 React Native 应用程序后面。
使用这个软件包,你可以:在Android中运行http服务器,使用Node流,与文件系统接口,从React Native中的JS线程中卸载一些繁重的处理,等等!在Android中运行真正的Node.js,您可以执行Node.js桌面上可以执行的所有操作。
产品特点:
- 使用 React Native 作为 UI,NodeJS 作为后台服务
特点:
- 派生自 NodeBase
- 与 Android 上的 node 非常相似(在单独的线程上使用 Node 运行)
Service
- 而是编译/用作应用程序,而不是嵌入式共享库
node
- NodeJS 应用程序代码位于
{projectRoot}/background
- NodeJS 可执行文件位于
/android/src/main/res/raw/bin_node_v710
- 在构建时,Node 应用程序被压缩,在 '/android/src/main/res/raw/{appName} 解压缩
- 调用 NodeJS 服务,就像从命令行运行一样,传递参数
- 节点服务在 RN 中可通过导入
RNNode
react-native-node
-
react-native-node
还包含在构建时传输节点代码的 CLI
- 示例项目通过 REST 从 React Native 到 NodeJS 服务进行通信
- 在节点端运行服务器
express
http://localhost:5000
优点:
缺点:
- 非常新的项目,只有实验代码
- 附带旧的NodeJS版本(但DIY构建较新的版本)
7.1.0
- 在 RN 和 Node 应用程序之间没有简单的通信方式(基于 REST)
- 节点应用上没有调试支持。真的很难知道发生了什么
状态 (2017-08-17)
我的目标是 React Native + NodeJS。这是我的活动状态:
- 将 NodeJS v7.x 版本编译为可执行文件的工作原理
- 将 NodeJS v7.4.0 编译到 v7.9.0 可与新的 J2V8 构建系统配合使用
- 编译 NodeJS v8.1.2 将很快与 J2v8 一起使用(编译
libc++
)
-
react-native-node
确实编译,但尽管尝试了很多,但仍无法运行
-
node-on-android
工作正常,但仅节点应用程序开发和 64 位与 RN 不兼容
我决定与以下因素结合使用:react-native-node
J2V8
React Native + NodeJS 现在正在工作!看:0.46.4
7.9.0
我的用例:具有P2P去中心化网络的胖客户端
我正在考虑CQRS(命令-查询-责任-隔离)设计:
- react-native UI 是从从节点服务查询的视图构造的
- react-native UI 操作在节点后台服务上触发命令
- 后台服务处理网络消息、传入命令、触发事件
- 事件存储在 Realm DB 中,形成前后之间的桥梁
细节:Realm.io 来桥接Android胖客户端应用程序中的本机NodeJS + React Native(CQRS风格)
结论
即使经过多年人们试图将NodeJS移植到Android,仍然没有真正好的解决方案,这是开创性的。
在设置项目和构建环境时会遇到许多障碍和错误,但一旦设置,您就可以在手机上享受Node的全部功能。