在Android上运行NodeJS的可行选项(2017年8月)
有一堆旧的线程处理在Android上运行NodeJS。 其中大多数不再可行(JXCore)和/或提供令人困惑,过时,不完整或错误的信息。
因此,我调查了目前似乎是(截至2017年8月)可行的方法,并find了三个可能的候选人。
要决定他们之间我想知道:
- 这些方法之间的主要区别
- 在每种方法上具体的亲和和骗局
- 可能的障碍,挑战和缺点
- 你知道其他可行的select吗?
可行的方法是 :
- 运行包含NodeJS ( J2V8 )的V8 javascript引擎,
- 直接使用NodeJS,embedded为本机库( node-on-android )
- 将React Native与NodeJS应用程序即服务( react-native-node )
除此之外,我发现了一些相关的有趣资源:
- NPM直接使用Termux直接安装NodeJS而不生根(不适用于最终用户)
- LiquidCore – 原生移动微应用程序devenv(没有调查,有趣的概念)
- dna2oslab – 为节点可执行文件提供了一个工作的NodeJS构build脚本
- 为Android构buildNodeJS – 使用有用的编译技巧和示例项目的博客
调查可行的select
[ 注意:这个答案包含原始问题中的发现]
我已经调查了更多的各种选项,这里有一些初步发现。
编译NodeJS
每个选项都使用为Android编译的某种forms的NodeJS。 但是要使用任何选项,您可能要编译到不同的Node,Android和体系结构(x86,ARM,ARM64等)版本。
这是有问题的。 NodeJS有一个android-configure
脚本,但是这在我尝试的大多数组合中都会导致错误。 我为一个工作的构build脚本创build了一些github问题。 在这个问题结果收集:
- 针对Android ARM Node 7.x或8.x共享库的工作构build脚本
总结:
- 共享库构build全部失败(除非在Android上进行物理构build,请参见下文)
- 带有NodeJS(
libnode.a
)的静态链接在libj2v8.so
中的libj2v8.so
适用于7.x,最高可达7.9.0
- build-as-node-executable 7.x(使用dna2oslab构build脚本)
@mafintosh使用了一个有趣的解决方法:使用Termux将节点传输到设备, 并在那里进行编译 (需要很多空间和时间,但工作正常)。
1.运行包含NodeJS ( J2V8 )的V8 javascript引擎,
J2V8是一组用于V8的Java绑定。 J2V8专注于性能和与V8的紧密集成。 […] [它]强制JS和Java代码之间的更静态types系统,但它也提高了性能,因为没有创build中间对象。 […]
构buildJ2V8需要构build本地部分和Java库(.jar / .aar文件)。 为了构build本地部分,我们首先将node.js构build为一个库,然后将J2V8静态链接到该库。 […]
对于交叉编译,J2V8使用Docker(android,linux,windows)和Vagrant(macos)。
请参阅slideshare: 在Java世界中运行 NodeJS(或参阅InfoQvideo ,32分钟)。
特点 :
- 用更强大的v8replaceJavaScriptCore引擎(使用NodeJS)
- 通过添加的J2V8 JNI / Java层支持multithreading(线程/工作者)
- 每个线程都可以拥有自己的独立V8实例
- 2路js-to-java桥接(从脚本调用java,反之亦然)
- 双向集成的错误/exception处理
- 美丽的交叉编译交互式构build系统( 作品中 )
- Chromedebugging支持
- 其他人,键入arrays,ES6支持,…
特点 :
- 指定要在
build_system/build_settings.py
编译的版本 -
使用
python build.py --interactive
开始构build,select构build:[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
-
select构build步骤(或
all
):NodeJS --> CMake --> JNI --> Optimize --> Java/Android --> JUnit
-
将V8编译为共享库
libj2v8_{platform}_{abi}.{ext}
- 注 :
nodejs
构build步骤不能build立节点共享库(错误),创build静态libnode.a
链接到libj2v8.so
- 注 :
- 有一个JNI层可以让Java可以访问v8的大部分内容
- 在Java中实现的附加function(例如JS < – > Java桥)
- 最终的构build输出是一个Gradle
.aar
,作为项目依赖包含在内
优点 :
- 相对活跃的项目
- 良好的质量代码,包括Javaunit testing
- 将Java的全部function添加到您的应用程序devise工具包中
- 非常直观的构build系统(一旦完成)
缺点 :
- 很less,大多是过时的使用文件
- 特别是无证的用于大型(r)规模的JS项目
- 许多必须维护的JNI胶水代码
- 项目维护不善(很多旧的公开问题,非合并的公关)
- 一些公关人员连续两年没有得到回应。 不好
- 比其他选项更难以理解J2V8项目设置(许多文件)
- 许可问题 (EPL 1.0许可中的“保留所有权利”)
2.直接使用NodeJS,embedded为本地库( node-on-android )
Android上的节点通过在Android应用程序中使用共享库运行Node.js工作。 然后捆绑一个托pipe你的UI代码的
WebView
。 所有的UI只是经典的HTML / CSS / JS。在节点应用程序中,您可以要求
node-on-android
访问WebView。 您可以使用它在WebView
加载一个html页面。
根据node-on-android
创造者( @mafintosh )这比J2V8更容易和更好,因为它直接编译V8 作为真实的东西 。
特点 :
- 构build完整的NodeJS应用程序,包括UI(通过本机WebView)
特点 :
- gradle
app
项目中的相关目录/文件:-
app/src/main/include/node
和节点.h
头 - 使用
libc++_shared.so
和libnode.so
app/src/main/jniLibs/arm64-v8a
-
app/src/main/cpp
与native-lib.cpp
(包括node.h
) - Java代码只是在一个单独的线程中运行一个节点运行的
Service
-
- 没有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软件包
优点 :
- 简单的项目,没有太多的pipe道代码
- 随附最新的v8.x节点版本
- 简单的基于HTML的应用程序UI编程(例如使用choo )
- 开箱即用:)
缺点 :
- 很新的项目,只有实验代码还在
- 来的只是为了
arm64
架构(全面的移动支持计划,或DIY构build)- 注意 :64位不能与React Native组合( 不支持64位 )!
- 没有本地用户界面(除非在Gradle / Java / XML中编码)
- Node应用程序没有debugging支持(AFAIK,但也许你可以连接到WebView)
3.将React Native与NodeJS应用程序即服务( react-native-node )
在后台运行真正的 Node.js进程,位于React Native应用程序的后面。
使用这个软件包你可以:在Android中运行http服务器,使用节点stream,与文件系统交互,在React Native的JS线程中卸载一些繁重的处理,等等。 在Android中运行真正的Node.js,可以完成Node.js在桌面上的所有function。
特点 :
- 使用React Native作为UI,NodeJS作为后台服务
特点 :
- 派生自NodeBase
- 非常类似于Android上的节点(在单独的线程上运行带有节点的
Service
)- 但
node
被编译/用作应用程序,而不是embedded式共享库 - NodeJS应用程序代码位于
{projectRoot}/background
- NodeJS可执行文件位于
/android/src/main/res/raw/bin_node_v710
- 在构build时,Node应用程序被tarballed,解压到`/ android / src / main / res / raw / {appName}
- 调用NodeJS服务就好像从命令行运行一样,传递参数
- 但
- 节点服务
RNNode
通过导入react-native-node
在RN中可用-
react-native-node
还包含构build时传输节点代码的CLI
-
- 示例项目通过REST从React Native通信到NodeJS服务
- 在节点端的
http://localhost:5000
上运行express
服务器
- 在节点端的
优点 :
- 简单的项目,没有太多的pipe道代码
- 显而易见:在Android上使用NodeJS反应原生支持!
- 节点作为可执行文件可能会与64位设备+ react-native一起工作
缺点 :
- 很新的项目,只有实验代码还在
- 来自旧的NodeJS
7.1.0
版本(但DIY自己build立新的) - RN和Node应用程序之间没有简单的通信方式(基于REST)
- 需要扩展REST API或推出自己的机制
- Node应用程序没有debugging支持。 真的很难知道发生了什么事
状态(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
会进行编译,但是尽pipe尝试了很多次,仍然无法运行 -
node-on-android
工作,但节点的应用程序开发和64位与RN不兼容
我决定将react-native-node
与J2V8
结合起来,因为:
- 大交叉编译构buildPR: https : //github.com/eclipsesource/J2V8/pull/327
- 构build成一个很好的J2V8
.aar
,很容易包含在Gradle中
React Native 0.46.4
+ 7.9.0
现在正在运行! 看到:
我的用例: 与P2P分散networking的胖客户端
我正在考虑CQRS(命令 – 查询 – 责任 – 隔离)devise:
- react-native UI是从节点服务查询的视图构build的
- 反应原生UI操作触发节点后台服务上的命令
- 后台服务处理networking消息,传入命令,触发事件
- 事件存储在Realm DB中,形成前后之间的桥梁
详细信息: Realm.io在Android胖客户端应用程序(CQRS风格)中桥接本机NodeJS + React Native
结论
即使经过多年尝试将NodeJS移植到Android之后,仍然没有真正的好解决scheme,这是开拓性的。
在设置项目和构build环境时,预计会遇到许多障碍和错误,但是一旦安装完毕,您就可以在手机上享受Node的全部function。
我收到了来自NodeBase的创build者@ dna2github的答复 (非常感谢!),我将在这里(包括许可)包括在内:
嗨,
Thx为您的问题。 在我看来,我会做一个简短的回答。
1.在包含NodeJS的android上运行V8 javascript引擎
优点:
- 与Java世界整合; 可以完全控制代码。
缺点:
- 有点难以集成第三包(需要时间来学习如何)。
- 需要了解NodeJS和V8的东西以及J2V8文档(它会消耗很长时间)。
2.将NodeJS编译为本地库(使用node-on-android)
优点:
- 专注于js开发,无需考虑android方面。
- 学习时间less; 类似cordova电话….
缺点:
- js app => apk是一个黑盒子。
3.使用Termux在Android上运行NodeJS
优点:
- 灵活
缺点:
- 没有gui
4.其他有趣的方法
不和LiquidCore相似; build立微服务,尤其是从url,我认为,是解决iOS上没有直接的可用存储。 Android部分的react-native-node基于NodeBase方法并使用预编译的二进制文件。
对于NodeBase:
优点:
- 类似于3; 不同的是,它有自己的GUI启动/停止应用程序。
- 它可以成为一切的模板; 例如,如果想运行django,则只需要将节点replace为python; 铁轨,ruby…
缺点:
- 本地进程访问问题; 该进程无法inheritance从Android应用程序的访问。
- 快乐的玩具快乐的开源不像一个商业应用程序; 如果要分发给客户需要更多的devise
首先,我在terminal运行节点; 我发现只有dev可以轻松地使用它来启动js应用程序。 我的朋友和家人也想要一些工具,比如批量打印图片上的水印。 NodeBase是为他们创build的,以便于开始/停止应用程序。 然后他们只需要打开浏览器来使用它。 我创buildNodeBase的另一个想法是,我们可以构build可共享的应用程序,可以在同一个Wi-Fi上共享。 当主持人启动一个应用程序,它可以被近人访问。 然后他们可以一起工作和玩耍。 例如,我们玩狼人,没有法官的时候,我们将启动狼人应用程序,为第一轮做一名法官。 我们还可以通过下载/上传在设备之间共享文件。
对于我来说,我可以灵活地构build我想要的东西,例如我想让我的Android成为机器学习的跑者; 它可以帮助我随时运行机器学习程序(使用node和python,因此在我的另一个回购中: dna2oslab着重于构build二进制文件)来利用手机的运行时间。
对于你,如果想在短时间内移植你的应用程序,我推荐2; 如果你有时间和其他资源,1更好。 3如果你只是做一个玩具/演示。 另外4个总是可能的,只是做你的想象力来创作作品。
最好的祝福,七