在過去的幾天里,我有了開發生涯中有意義的經歷之一, 想在這里跟大家分享。
  現在我們已經讓 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,F在我們來試一下,只需要簡單的使用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 活躍起來,用于為移動設備開發應用!