Возможные варианты запуска NodeJS на Android (август 2017 г.)
Существует множество старых SO-потоков, посвященных запуску NodeJS на Android. Большинство из них больше не являются жизнеспособными (JXCore) и / или предоставляют запутанную, устаревшую, неполную или ошибочную информацию.
Поэтому я исследовал то, что кажется в настоящее время (по состоянию на август 2017 года) жизнеспособными подходами, и нашел трех возможных кандидатов.
Чтобы решить между ними, я хотел бы знать:
- основные различия между этими подходами
- конкретные плюсы и минусы на каждом подходе
- вероятные препятствия, проблемы и недостатки
- Вы знаете о других жизнеспособных альтернативах?
Возможные подходы:
- Запуск движка JavaScript V8, который включает в себя NodeJS ( J2V8)
- Используйте NodeJS напрямую, встроенный как нативная библиотека ( node-on-android)
- Объединение React Native с NodeJS app-as-a-service ( response-native-node)
Кроме того, я нашел ряд связанных интересных ресурсов:
- NPM устанавливает NodeJS напрямую, используя Termux без рута (не для конечных пользователей)
- LiquidCore - нативное мобильное микро-приложение devenv (не исследовано, интересные концепции)
- dna2oslab - имеет рабочий скрипт сборки NodeJS для исполняемых файлов узлов
- Сборка NodeJS для Android - блог с полезными советами по компиляции и примером проекта
5 ответов
Изучение жизнеспособных вариантов
[ ПРИМЕЧАНИЕ. Этот ответ содержит выводы, которые были в первоначальном вопросе]
Я изучил различные варианты немного больше, и вот некоторые предварительные выводы.
0. Компиляция NodeJS
Каждый из вариантов использует ту или иную форму NodeJS, скомпилированную для Android. Но чтобы использовать любую опцию, вы, вероятно, захотите скомпилировать для разных версий Node, Android и архитектуры (x86, ARM, ARM64 и т. Д.).
Это проблематично. NodeJS имеет android-configure
сценарий, но это приводит к ошибкам в большинстве комбинаций, которые я пробовал. Я создал несколько проблем с GitHub для рабочего скрипта сборки. В этом выпуске собраны результаты:
Подвести итоги:
- Все библиотеки с общей библиотекой терпят неудачу (кроме случаев физического построения на вашем Android, см. ниже)
- J2V8 с NodeJS (
libnode.a
) статически связаны вlibj2v8.so
работает на 7.x до7.9.0
- исполняемый файл build-as-node работает для 7.x (используя скрипт сборки dna2oslab)
@Mafintosh использовал один интересный обходной путь: перенести Node на устройство с помощью Termux и выполнить там компиляцию (требует много места и времени, но работает).
1. Запуск движка JavaScript V8, который включает в себя NodeJS ( J2V8)
J2V8 - это набор привязок Java для V8. J2V8 фокусируется на производительности и тесной интеграции с V8. [...] [который] создает более статическую систему типов между кодом JS и Java, но также повышает производительность, поскольку промежуточные объекты не создаются. [...]
Сборка J2V8 требует сборки как собственных частей, так и библиотеки Java (файл.jar/.aar). Чтобы собрать нативные части, мы сначала собираем node.js как библиотеку, а затем статически связываем J2V8 с этим. [...]
Для кросс-компиляции J2V8 использует Docker (android, linux, windows) и Vagrant (macos).
См. Слайдшер: Запуск NodeJS в мире Java (или см. Видео InfoQ, 32 мин.)
Особенности:
- заменить движок JavaScriptCore на более мощный v8 (с NodeJS)
- поддержка многопоточности (потоки / рабочие) через добавленный слой JNI / Java J2V8
- каждый поток может иметь свой собственный изолированный экземпляр V8
- Двухсторонний мост js-to-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, чтобы сделать большие части v8 доступными для Java
- Дополнительные функции (например, JS <-> Java bridge), реализованные в Java
- Окончательный результат сборки - Gradle
.aar
включить в качестве зависимости проекта
Плюсы:
- Относительно активный проект
- Код хорошего качества, включая модульные тесты Java
- Добавляет всю мощь Java в ваш инструментарий дизайна приложений
- Отличная, интуитивно понятная система сборки (после завершения)
Минусы:
- Маленькая, в основном устаревшая документация по использованию
- Особенно недокументировано использование в больших (r) масштабных проектах JS
- Много JNI-кода клея, который необходимо поддерживать
- Проект не в хорошем состоянии (много старых открытых вопросов, не объединенные PR)
- Некоторые пиарщики тусуются 2 года, даже не получив ответа. Нехорошо
- Труднее понять настройку проекта J2V8 (много файлов), чем другие варианты
- Вопрос лицензирования ("Все права защищены" в лицензии EPL 1.0)
2. Используйте NodeJS напрямую, встроенный как нативная библиотека ( node-on-android)
Node на Android работает, запустив ваш Node.js внутри приложения Android с помощью общей библиотеки. Затем он связывает
WebView
который содержит ваш код пользовательского интерфейса. Весь пользовательский интерфейс - это просто классический html/css/js.В приложении узла вы можете требовать
node-on-android
получить доступ к WebView. Вы можете использовать это для загрузки HTML-страницы вWebView
,
В соответствии с node-on-android
Creator ( @mafintosh), это проще и лучше, чем J2V8, поскольку он компилирует V8 напрямую как реальную вещь.
Особенности:
- Создавайте полноценные приложения NodeJS, включая пользовательский интерфейс (через собственный 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 для
libnode.so
, такprivate native void startNode(String... app);
отображается как ошибка в IDE (но компилируется) - Проект NodeJS находится в
android/app/src/main/assets/node
- Код NodeJS переносится во временное хранилище и выполняется оттуда
- Приложение NodeJS определяет представления для загрузки в WebView через открытые
loadUrl
функция- Сервис Node доступен через пакет NPM
node-on-android
- Сервис Node доступен через пакет NPM
Плюсы:
- Простой проект, не так много кода
- Поставляется с последней версией Node v8.x из коробки
- Простое программирование пользовательского интерфейса приложения на основе HTML (например, с помощью choo)
- Работает из коробки:)
Минусы:
- Очень новый проект, только экспериментальный код
- Приходит только для
arm64
архитектура (планируется полная поддержка мобильных устройств или сборка своими руками)- Примечание: 64-битная версия не может быть объединена с React Native ( без поддержки 64-битной версии)!
- Нельзя использовать собственный интерфейс (кроме случаев написания кода в Gradle/Java/XML)
- Отсутствует поддержка отладки в приложении Node (AFAIK, но, возможно, вы можете как-то присоединиться к WebView)
3. Объединение React Native с NodeJS app-as-a-service ( response-native-node)
Запустите настоящий процесс Node.js в фоновом режиме за приложением React Native.
С помощью этого пакета вы можете: запускать http-серверы в Android, использовать потоки Node, взаимодействовать с файловой системой, снимать с себя тяжелую обработку из потока JS в React Native и многое другое! Запустив настоящий Node.js в Android, вы можете делать все, что может Node.js на рабочем столе.
Особенности:
- Используйте React Native для пользовательского интерфейса, NodeJS в качестве фоновой службы
Характеристики:
- Получено из NodeBase
- Очень похоже на узел на Android (запустить
Service
с узлом на отдельном потоке)- Но
node
компилируется / используется как приложение, а не как встроенная общая библиотека - Код приложения NodeJS находится в
{projectRoot}/background
- Исполняемый файл NodeJS находится в
/android/src/main/res/raw/bin_node_v710
- Во время сборки Node приложение упаковывается в папку `/android/src/main/res/raw/{appName}
- Сервис NodeJS вызывается так, как будто запускается из командной строки, передавая аргументы
- Но
- Узел обслуживания
RNNode
доступно в RN путем импортаreact-native-node
react-native-node
также содержит CLI, который передает код узла во время сборки
- Пример проекта связывается от React Native к сервису NodeJS через REST
- Работает
express
сервер включенhttp://localhost:5000
на стороне узла
- Работает
Плюсы:
- Простой проект, не так много кода
- Очевидно: Реагируйте на поддержку Native с помощью NodeJS на Android!
- Node-as-исполняемый файл, вероятно, будет работать с 64-разрядными устройствами
Минусы:
- Очень новый проект, только экспериментальный код
- Поставляется со старым NodeJS
7.1.0
версия (но сделай сам, построй новые) - Нет простого способа связи между приложениями RN и Node (на основе REST)
- Нужно расширить REST API или накатить собственный механизм
- Нет поддержки отладки в приложении Node. Действительно трудно понять, что происходит
Статус (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
потому что:
- Отличная кросс-компиляция PR: https://github.com/eclipsesource/J2V8/pull/327
- Строит в хороший J2V8
.aar
быть легко включенным в Gradle
React Native 0.46.4
+ NodeJS 7.9.0
сейчас работает! Увидеть:
Мой пример использования: толстый клиент с децентрализованной сетью P2P
Я имею в виду дизайн CQRS (команда-запрос-ответственность-разделение):
- Реактивный пользовательский интерфейс построен из представления, запрашиваемого из службы узла
- Реактивные действия пользовательского интерфейса запускают команды на фоновой службе узла
- Фоновая служба обрабатывает сетевые сообщения, входящие команды, запускает события
- события хранятся в Realm DB, которая образует мост между передней и задней
Подробная информация: Realm.io, чтобы соединить нативный NodeJS + React Native в толстом клиентском приложении Android (в стиле CQRS)
Заключение
Даже после многих лет попыток портировать NodeJS на Android все еще нет действительно хороших решений, это новаторство.
Ожидайте много препятствий и ошибок при настройке своего проекта и среды сборки, но после настройки вы сможете ощутить всю мощь Node на своем телефоне.
На сегодняшний день (март 2018 года) существует еще одна жизнеспособная альтернатива, еще не указанная в текущих ответах: Node.js для мобильных приложений.
По своей сути, проект предоставляет собственную библиотеку для встраивания Node.js в собственные приложения для Android и iOS; но он также поставляется с плагинами для React Native и Cordova.
Готовые двоичные файлы для библиотеки доступны для Android armeabi-v7a, x86, arm64-v8a, x86_64 и для 64-битной iOS.
Базовая библиотека - это https://github.com/nodejs/node-chakracore, которая, в свою очередь, является ветвью nodejs / node. Версия Android в основном представляет собой обычный Node.js, созданный в виде библиотеки, с несколькими исправлениями переносимости. Версия iOS использует движок ChakraCore вместо V8 (замена V8 на ChakraCore возможна благодаря изменениям в форке nodejs / node-chakracore).
Плагины React Native и Cordova упрощают добавление Node.js в приложения, созданные с использованием этих сред. Код Node.js запускается в отдельном движке и потоке, нежели фреймворк (React Native / Cordova). Связь между двумя мирами JavaScript достигается через мост обмена сообщениями, предоставляемый плагинами.
Дополнительная информация, включая некоторую документацию, доступна на веб-сайте проекта.
(Полное раскрытие: я работаю в компании, которая разрабатывает Node.js для мобильных приложений.)
Я автор LiquidCore. LiquidCore позволяет использовать полные реализации Node.js как для Android, так и для iOS (поддержка iOS была только что выпущена в версии 0.5.0 - сентябрь 2018 года).
LiquidCore предназначен для одновременной работы нескольких экземпляров Node внутри собственного мобильного приложения. Каждый экземпляр имеет свою собственную виртуальную файловую систему и собственную поддержку MySQL. Цель проекта - создать полноценные "микро-приложения" с использованием JavaScript/WebAssembly, которые затем могут быть встроены в другие приложения, и я все еще работаю над достижением этой цели. Но на сегодняшний день это прекрасно работает, если вы просто хотите игровую площадку Node.js.
Если вы хотите узнать, на что он способен, для Android и iOS есть простое консольное приложение для узлов.
Я получил ответ от @ dna2github, создателя NodeBase (большое спасибо!), Который я включу сюда (с разрешения):
Привет,
Спасибо за ваш вопрос. Я сделаю краткий ответ, на мой взгляд.
1. Запуск движка JavaScript V8 на Android, который включает в себя NodeJS
плюсы:
- интегрированный с миром Java; может получить полный контроль над кодом.
минусы:
- немного сложно интегрироваться с третьими пакетами (нужно время, чтобы узнать, как).
- нужно узнать о NodeJS и V8, а также о документах J2V8 (это занимает много времени).
2. Скомпилируйте NodeJS как собственную библиотеку (используя node-on-android)
плюсы:
- сосредоточиться на JS Dev и не нужно учитывать сторону Android.
- меньше учебного времени; похож на телефонную пробку Кордова....
минусы:
- js app => apk - это черный ящик.
3. Запуск NodeJS на Android с использованием Termux
плюсы:
- гибкий
минусы:
- нет гуй
4. Другие интересные подходы
Не знаком с LiquidCore; Я думаю, что построить микро сервис, особенно из URL, - это не разрешить прямое доступное хранилище на iOS. response-native-node Android-часть основана на методе NodeBase и использует предварительно собранный двоичный файл.
Для NodeBase:
плюсы:
- аналогично 3; Разница в том, что у него есть собственный графический интерфейс для запуска / остановки приложения.
- это может быть шаблон для всего; например, если вы хотите запустить django, вам просто нужно заменить узел на python; рельсы, рубин...
минусы:
- проблема с собственным доступом к процессу; процесс не может наследовать доступ из приложения Android.
- happy toy happy open source не похож на коммерческое приложение; нужно больше дизайна, если хотите раздать клиентам
Сначала я запускаю узел в терминале; Я считаю, что только Dev может легко использовать его для запуска приложения JS. Мои друзья и семьи также хотят, чтобы некоторые инструменты, например, делали водяной знак на изображении в партии. NodeBase создан для того, чтобы они могли легко запускать / останавливать приложение. Тогда им просто нужно открыть браузер, чтобы использовать его. Моя другая идея создать NodeBase - это то, что мы можем создавать совместные приложения, которые можно использовать в одном и том же Wi-Fi. Когда хост запускает приложение, его могут посещать близкие люди. Тогда они могут работать и играть вместе. Например, мы играем в оборотня и, когда нет судьи, мы запускаем приложение для оборотня, чтобы иметь судью в первом раунде. Мы также можем обмениваться файлами между устройствами с помощью загрузки / выгрузки.
Для меня, я могу гибко строить то, что я хочу, например, я хотел бы сделать свой Android как бегун машинного обучения; это может помочь мне запускать программы машинного обучения в любое время (с помощью узла и python, поэтому в моем другом репозитории: dna2oslab сосредоточена на создании двоичных файлов), чтобы использовать время работы телефона.
Для вас, если вы хотите портировать ваше приложение в короткие сроки, я рекомендую 2; если у вас есть время и другие ресурсы, лучше 1. 3 если просто сделать игрушку / демо. 4 другое всегда возможно и просто делай свое воображение, чтобы создавать произведения.
С наилучшими пожеланиями, Семерка
Я попытался использовать J2V8 в своем приложении Java для Android, чтобы запустить JS-скрипт через node.js. Это терпит неудачу с этой ошибкой:
java.lang.UnsupportedOperationException: StartNodeJS не поддерживается.
Ответ от J2V8 был:
"Оболочки узлов недоступны в Android, они доступны только на платформах рабочего стола (windows, mac, linux). Это ожидаемое поведение, пока у нас не появятся двоичные файлы узлов для Android".
Насколько я знаю, в настоящее время нет планов по внедрению упаковщиков узлов для Android.
Спасибо,
Алекс Доннини