在Android上运行NodeJS的可行选项(2017年8月)

有一堆旧的线程处理在Android上运行NodeJS。 其中大多数不再可行(JXCore)和/或提供令人困惑,过时,不完整或错误的信息。

因此,我调查了目前似乎是(截至2017年8月)可行的方法,并find了三个可能的候选人。

要决定他们之间我想知道:

  • 这些方法之间的主要区别
  • 在每种方法上具体的亲和和骗局
  • 可能的障碍,挑战和缺点
  • 你知道其他可行的select吗?

可行的方法是

  1. 运行包含NodeJS ( J2V8 )的V8 javascript引擎,
  2. 直接使用NodeJS,embedded为本机库( node-on-android )
  3. 将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.solibnode.so app/src/main/jniLibs/arm64-v8a
    • app/src/main/cppnative-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

优点

  • 简单的项目,没有太多的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-nodeJ2V8结合起来,因为:

  • 大交叉编译构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个总是可能的,只是做你的想象力来创作作品。

最好的祝福,七