在 Android 上运行 ClojureScript

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

[[151938]]

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

现在我们已经让 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。

 

  1. cljs.core.apply.call(null,cljs.core.inc,new cljs.core.PersistentVector(null15, 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已经成功启动了。

 

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

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

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

 

  1. I got 3 
  2.  
  3. (+ 1 2) = 3 

 

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

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

简直就是一场暴风雨!

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

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

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

 

  1. Clojure ~14 秒 
  2.  
  3. Clojure / Skummet ~11 秒 
  4.  
  5. ClojureScript ~2 秒 

 

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

责任编辑:chenqingxiang 来源: oschina
相关推荐

2011-10-12 11:24:44

AndroidPC

2012-01-11 10:41:37

Windows 8Android应用

2012-03-08 22:29:41

Android

2009-08-05 15:23:04

ExtJS Andro

2011-11-02 13:56:13

2019-04-23 09:48:21

KubernetesPostgreSQL

2020-07-20 18:30:44

Fedora 32DockerLinux

2011-03-25 11:21:36

NagiosLinux

2010-05-21 15:23:25

ipadSAP

2010-10-09 08:58:03

NginxRuby on Rai

2020-11-11 15:02:27

Android运行手机

2010-11-18 14:47:49

2020-06-11 14:33:10

MacBookLinux软件

2021-06-25 16:08:14

Android 应用Windows

2023-01-26 11:56:31

Kubernete虚拟机k3s

2021-10-03 14:47:26

Fedora CoreGitHub Acti运行器

2019-06-03 09:15:15

KubernetesKafka数据库

2017-08-15 19:20:51

AndroidHttpServer

2011-10-09 14:45:58

Alien DalviiOSAndroid
点赞
收藏

51CTO技术栈公众号