在Android上运行NodeJS的可行选项(2017年8月)
有很多旧的SO线程处理在Android上运行NodeJS的问题。其中大多数不再可行(JXCore)和/或提供令人困惑,过时,不完整或错误的信息。
因此,我调查了目前(截至2017年8月)似乎可行的方法,并找到了三种可能的候选方法。
要在他们之间做出决定,我想知道:
- 这些方法之间的主要区别
- 每种方法的具体优缺点
- 可能的障碍,挑战和缺点
- 您知道其他可行的选择吗?
:
- 运行包[NodeJSJ2V8的V8 JavaScript引擎
- 直接使用NodeJS,嵌入为本机库node-on-android
- 将React Native与NodeJS应用即服务react-native-node结合
除此之外,我发现了许多相关的有趣资源:
- NPM直接使用Termux来安装NodeJS而无需生根(不适用于最终用户)
- LiquidCore-本机移动微型应用程序开发(未经调查,有趣的概念)
- dna2oslab-具有适用于节点可执行文件的有效NodeJS构建脚本
- 构建适用于Android的NodeJS具有有用的编译技巧和示例项目的
回答:
回答:
[ 此答案包含原始问题中的发现]
我已经研究了各种选择,这里是一些初步的发现。
0.编译NodeJS
每个选项都使用某种形式的为Android编译的NodeJS。但是要使用任何选项,您可能希望将其编译为不同的Node,Android和体系结构(x86,ARM,ARM64等)版本。
这是有问题的。NodeJS有一个android-configure
脚本,但这会导致我尝试过的大多数组合出现错误。我为工作的构建脚本创建了许多github问题。在本期中,收集结果:
总结一下:
- 共享库构建全部失败(除非在android上进行物理构建,请参见下文)
- 与NodeJS(
libnode.a
)静态链接的J2V8libj2v8.so
适用于7.x直至7.9.0
- 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)。
:
- 用功能更强大的v8替换JavaScriptCore引擎(使用NodeJS)
- 通过添加的J2V8 JNI / Java层支持多线程(线程/工作者)
- 每个线程都可以拥有自己的隔离V8实例
- 2路js到Java桥(从脚本调用Java,反之亦然)
- 2路集成错误/异常处理
- 美丽的交叉编译交互式构建系统
- chrome调试支持
- 其他,类型数组,ES6支持,…
:
- 指定要编译的版本
build_system/build_settings.py
- 只需使用即可开始构建
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}
- :
nodejs
构建步骤无法构建Node共享库(错误),创建libnode.a
要链接的静态对象libj2v8.so
- 拥有一个JNI层,以使Java可以访问v8的大部分内容
- 用Java实现的附加功能(例如JS <-> Java桥)
- 最终构建输出是
.aar
作为项目依赖项包括在内的Gradle
- :
:
- 相对活跃的项目
- 高质量的代码,包括Java单元测试
- 将Java的全部功能添加到您的应用程序设计工具包中
- 出色,直观的构建系统(完成后)
:
- 很少,大多数是过时的使用文档
- 大型JS项目中的用法尤其没有记载
- 必须维护的许多JNI粘合代码
- 项目维护不力(许多旧的未解决问题,未合并的PR)
- 一些公关公司徘徊了两年,甚至没有得到回应。不好
- 比其他选项更难理解J2V8项目设置(许多文件)
2.直接使用NodeJS,作为本机库嵌入([node-on-android](https://github.com/node-on-
mobile/node-on-android))
android上的Node通过使用共享库在android应用中运行Node.js来工作。然后
WebView
,它捆绑了一个托管您的UI代码的。所有的UI都是经典的html / css / js。在节点应用程序中,您可能需要
node-on-android
访问WebView。您可以使用它在中加载html页面WebView
。
根据node-on-android
创建者(@mafintosh)的说法,这比J2V8更容易和更好,因为它直接将V8编译
为真实的东西 。
:
- 构建完整的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
在单独线程中运行的with节点
- 没有用于的JNI
libnode.so
,因此private native void startNode(String... app);
在IDE中显示为错误(但可以编译) - NodeJS项目位于
android/app/src/main/assets/node
- NodeJS代码被传输到临时存储并从那里执行
- NodeJS应用程序指定要通过公开
loadUrl
功能 在WebView中加载的视图- 可通过NPM软件包访问节点服务
node-on-android
- 可通过NPM软件包访问节点服务
:
- 简单的项目,没有太多的管道代码
- 随附最新的v8.x Node版本
- 基于HTML的简单应用程序UI编程(例如,使用choo)
- 开箱即用:)
:
- 非常新的项目,仍然只有实验代码
- 仅用于
arm64
架构(已计划完整的移动支持或DIY构建) :64位不能与React Native结合使用不支持64位! - 无法使用本机UI(除非使用Gradle / Java / XML进行编码)
- Node应用程序上没有调试支持(AFAIK,但也许您可以通过某种方式连接到WebView)
3.将React Native与NodeJS应用即服务react-native-node结合
在React Native应用程序的后台在后台 运行 Node.js进程。
使用此软件包,您可以:在Android中运行http服务器,使用Node流,与文件系统接口,从React
Native的JS线程中卸载一些繁重的处理工作,等等!在Android中运行真正的Node.js,您可以执行桌面上Node.js可以执行的所有操作。
:
- 将React Native用于UI,NodeJS作为后台服务
:
- 派生自NodeBase
- 与Android
Service
上的Node 非常相似(在单独的线程上与Node一起运行)- 但是
node
被编译/用作应用程序,而不是嵌入式共享库 - NodeJS应用程序代码位于
{projectRoot}/background
- NodeJS可执行文件位于
/android/src/main/res/raw/bin_node_v710
- 在构建时,Node应用被压缩,并在`/ android / src / main / res / raw / {appName}中解压缩
- 就像从命令行运行一样调用NodeJS服务,并传递args
- 但是
RNNode
通过导入,RN中可以使用节点服务react-native-node
react-native-node
还包含在构建时传输Node代码的CLI
- 示例项目通过REST从React Native到NodeJS服务进行通信
- 在节点端运行
express
服务器http://localhost:5000
- 在节点端运行
:
- 简单的项目,没有太多的管道代码
- 显而易见:在Android上使用NodeJS响应本机支持!
:
- 非常新的项目,仍然只有实验代码
- 带有旧的NodeJS
7.1.0
版本(但可以自己构建较新的版本) - 在RN和Node应用之间进行通信的简便方法(基于REST)
- 需要扩展REST API或使用自己的机制
- Node应用程序上没有调试支持。真的很难知道发生了什么
回答:
我的目标是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
可以,但是仅节点应用程序开发和与RN不兼容的64位
我之所以决定合并react-native-node
,J2V8
是因为:
- 很棒的交叉编译构建PR:https : //github.com/eclipsesource/J2V8/pull/327
- 内置
.aar
于精美的J2V8中,可轻松包含在Gradle中
React Native 0.46.4
+ NodeJS 7.9.0
现在可以使用了!看到:
- https://github.com/staltz/react-native-node/issues/5#issuecomment-323049897
我的用例:
我正在考虑一个CQRS(命令-查询-责任-隔离)设计:
- react-native UI是从节点服务查询的视图构造的
- react-native UI操作触发节点后台服务上的命令
- 后台服务处理网络消息,传入命令,触发事件
- 事件存储在Realm DB中,该数据库构成了前后之间的桥梁
回答:
即使经过多年尝试将NodeJS移植到Android上的人们,仍然没有真正好的解决方案,它是先锋。
在设置项目和构建环境时,会遇到许多障碍和错误,但是一旦设置,您就可以在手机上享受Node的全部功能。
以上是 在Android上运行NodeJS的可行选项(2017年8月) 的全部内容, 来源链接: utcz.com/qa/432391.html