在 Android 上运行 ClojureScript

在过去的几天里,我有了开发生涯中最有意义的经历之一, 想在这里跟大家分享。

现在我们已经让 ClojureScript 可以在 Android 上运行了。不是在一个 WebView 里面,也不是利用像 Cordova 这样的东西,而是实实在在的运行在一个嵌入式的 JavaScript 引擎中。到底发生了什么?

最近,我们做了一些工作创建出了一个 iOS 的 ClojureScript REPL 应用,Replete。整个看上去很酷,而对应的 Android 应用就只算勉强能创建出来。不幸的是,我的 Android 技术平平,也不能立马就上手。

不过,这方面 Tahmid Sadik 的技术还能上得了台面。

Tahmid 可以把UI都串起来,也能将 Rhino 实例化并对JavaScript语句进行计算,但是接下来让引导式的 ClojureScript 运行起来对他而言可谓是一次挑战。

不过在此之前,他必须在他的 app 里将 ClojureScript 引导起来。引导这个词被我特意标明,指出他需要用 Google 的 Closure 依赖管理系统把 ClojureScript 运行时启动起来,没有 JavaScript,也没有其他的优化(例如 :none 模式),根据需要,可以定义 CLOSURE_IMPORT_SCRIPT 环境变量。如果想包含一个 REPL,用这种方式来引入运行时是很重要的。这也为在你的 REPL 包含源码级的名字空间提供了支持。

实际上,Replete 也需要做这些,用到的是 Ambly 的一个功能。我当然知道,Replete 是一个独立的 REPL,并不需要 Ambly。不过我使用了一个小花招,可以复用这个功能,让 ClojureScript 启动在 Replete 里运行。

顺便说一下,我最初是打算用 React Native 来实现 Replete 的。结果发现,使用 React Native 的 ClojureScript 支持还为时尚早,而可以引导的 ClojureScript 确实只是初期的功能,要想能够实际工作还需要做很多努力。所以,对于 Replete,我还是保持简单吧,就算是 Goby 也没有用到。

对于上述的结果,好的一点是不需要 React Native 的依赖(Android 版还没有正式公开发布),也没有 Goby 的依赖(只支持 iOS)。Replete 内置的 ClojureScript 非常简洁,使用传统的 iOS 的 UI,事实证明这对 Tahmid 去完成同样功能的 Android 版很有帮助。

让我们回到故事的开始:本质上 Tahmid 复制了 Ambly 的 bootstrap 逻辑,按照顺序逐一的执行了在 Rhino 里的 JavaScript 语句。不过时不时的他会遇到一些奇怪的问题,我的记忆中几个月前也会遇到类似的问题,在研究过 Ambly 的代码后,我给了一点建议。

之后,他基本上可以引导成功 ClosureScriptle。

cljs.core.apply.call(null,cljs.core.inc,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [1], null))

这行就是(apply inc [1])需要绑定的JavaScript代码

然后Tahmid终于有了2.0。真棒!这应该是有史以来的第一次,在基于Android的嵌入式的Rhino上跑起来ClojureScript。

接下来,需要尝试用起来reader, analyzer, 和compiler。现在我们来试一下,只需要简单的使用Replete里的JavaScript,让Android的app执行Replete的read_eval_print函数,参数为字符串 (+ 1 2),如果工作正常,那么恭喜,ClojureScript已经成功启动了。

replete.core.read_eval_print.call(null,'(+ 1 2)')

且慢,Transit 里执行 goog.require('replete.core');的时候出了问题,应该是跟 randomUUID 有关。悲剧了,看上去显然还有很多地方需要处理。

不过没关系,Replete 之前一直尝试用不同的方式加载 analysis 缓存,感谢 Karl Mikkelsen,我们有了一个可用的版本只使用纯 JavaScript,没有任何依赖。把这个用起来之后,在把print回调弄好(这样类似 println 这样的方法就可以工作了),接下来 Tahmid 就通过Slack通知我:

I got 3
(+ 1 2) = 3

... 然后不断烦我,还会擅自发博客。就这样,引导的 ClojureScript REPL 在 Android 上诞生了!

Tahmid 在界面上封装了一些东西,修复了 JavaScript/ClojureScript 集成的一些小问题之后就发布了Replicator。

简直就是一场暴风雨!

现在,Tahmid 正在用 JavaScriptCore 替换 Rhino,这就没那么快了。

我认为这将使速度提升。这为我们在 Android 上使用 JavaScriptCore 进行本地交换的功能提供一些重要的基础。

从大图片来看,我真的认为 ClojureScript 在 Android 上运行很快。特别是使用 JavaScriptCore。对于这个观点的问题,可以看看 Bocko 对 Android 的 Vladimir Iakovlev 的端口在启动速度上的差异。

Clojure   ~14 秒

Clojure / Skummet   ~11 秒

ClojureScript   ~2 秒

以上是在模拟器上运行的结果,但是,我仍然认为它显示了 ClojureScript 真正的实现了在移动设备上减少计算延时的承诺。我认为是时候让 ClojureScript 活跃起来,用于为移动设备开发应用!

文章转载自 开源中国社区[https://www.oschina.net]

时间: 2024-09-08 06:43:18

在 Android 上运行 ClojureScript的相关文章

编译可在Android上运行的依赖库(一):glib库

编译可在Android上运行的依赖库(一):glib库 作者:寻禹@阿里聚安全 前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在"编译依赖库"一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库交叉编译到Android平台上才能成功的编译glib库,系列文章中除<编译可在Android上运行的glib库>外的其他交叉编译文章均是介绍如何对glib依赖库进行交叉编译.以上,所以叫系列文章,因

编译可在Android上运行的qemu user mode

编译可在Android上运行的qemu user mode 寻禹@阿里聚安全 前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码. 下文中的"NDK"若无特殊说明均指"Android NDK". 下文中"$NDK"表示的是NDK的根目录. 步骤 1. 下载并安装Android NDK 下载并安装Android NDK的过程在这里不做介绍. 2. 下载qemu 3. 设置NDK工具的

编译可在Android上运行的依赖库(三):libffi库

编译可在Android上运行的依赖库(三):libffi库 作者:寻禹@阿里聚安全 前言 libffi版本:3.2.1. 本文在Ubuntu 64位系统上对libffi项目进行交叉编译. 下文中的"NDK"若无特殊说明均指"Android NDK". 步骤 1. 下载并安装Android NDK 下载并安装Android NDK的过程在这里不做介绍. 2. 下载libffi 到libffi的官网去下载这个库的源码.官网地址:https://sourceware.or

编译可在Android上运行的依赖库(二):gettext库

编译可在Android上运行的依赖库(二):gettext库 作者:寻禹@阿里聚安全 前言 gettext版本:0.19.7. 本文在Ubuntu 64位系统上对gettext项目进行交叉编译. 下文中的"NDK"若无特殊说明均指"Android NDK". 注意:不要运行gettext源码目录下的autogen.sh文件.如果先运行autogen.sh然后运行configure再然后使用make命令编译时,编译会出错. 步骤 1. 安装必要的工具 如果不安装这些工

编译可在Android上运行的依赖库(五):pcre库

编译可在Android上运行的依赖库(五):pcre库 作者:寻禹@阿里聚安全 前言 pcre版本:8.38. 本文在Ubuntu 64位系统上对pcre项目进行交叉编译. 下文中的"NDK"若无特殊说明均指"Android NDK". 步骤 1. 下载并安装Android NDK 下载并安装Android NDK的过程在这里不做介绍. 2. 下载pcre 到pcre的官网去下载这个库的源码.官网地址:http://pcre.org/ 3. 设置NDK和SYSROO

编译可在Android上运行的依赖库(四):llibiconv库

编译可在Android上运行的依赖库(四):llibiconv库 作者:寻禹@阿里聚安全 前言 libiconv版本:1.14. 本文在Ubuntu 64位系统上对libiconv项目进行交叉编译. 下文中的"NDK"若无特殊说明均指"Android NDK". 注意:不要运行libiconv源码目录下的autogen.sh文件.如果先运行autogen.sh然后运行configure再然后使用make命令编译时,编译会出错. 步骤 1. 下载并安装Android

Wine 将支持在 Android 上运行 Windows 应用

想要在Linux或者Mac平台上运行Windows应用和游戏?Wine无疑是首选.未来几周开发团队不仅会推出最新版本,还有望披露关于 Windows-on-Android 系统的更多信息,意味着用户能够在Android系统上运行Windows应用. 不过这个项目还在早期开发阶段,Wine开发者目前致力于整合现有的CrossOver Android软件至现有的开源Windows API上,一旦完成之后允许在Android系统上运行Windows应用.不过在即将到来的Wine 2.0上我们并不会看到

C/C++交叉编译环境中编译可在Android上运行的可执行文件

X86架构的CPU采用的是复杂指令集(Complex Instruction Set  Computer,CICS),而ARM架构的CPU使用的是精 简指令集(Reduced Instruction Set  Computer,RISC).由于这两种架构的CPU使用了不同的指令集,因此在X86架 构上开发可运行在ARM架构上的程序就必须要使用交叉编译器. 通常交叉编译器和相关工具包含的了很多可执行文件以及大 量的共享库及头文件等资源.这些资源的集合称为交叉编译环境. 在Internet上可以找到

如何开发能在android上运行java web服务器?

问题描述 我想arm平台上使用android系统,请问:使用javaweb编程技术能开发web服务器应用程序到android系统下运行吗?使用mysql数据库是否可以?请高手指点.有兴趣的朋友来讨论. 解决方案 解决方案二:把手机作为服务器估计是几年或者几十年后的需求解决方案三:现在都在开发云计算了解决方案四:我说的情况是:用arm11平台通过串口连接一台设备,并用一个web服务器来实时接受和管理设备信息.该arm平台运行web服务器后,网络上的任意计算机都可以用浏览器来访问,实现设备的远程查看