如何在 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 活躍起來,用於為移動裝置開發應用!
相關文章
- 如何在 Android 上藉助 Wine 來執行 Windows AppsAndroidWindowsAPP
- win系統如何在mac上執行Mac
- 如何在 Windows 上執行 Linux 容器WindowsLinux
- 如何在 SAP BTP 上 手動執行 workflow
- 如何在Windows上脫離Cygwin執行Apache KafkaWindowsApacheKafka
- 使用 ARChon 執行時環境在 Ubuntu 上執行 Android 應用UbuntuAndroid
- 如何在Redis上儲存的資料上對Java執行分散式MapReduceRedisJava分散式
- 如何在Windows上使用Git建立一個可執行指令碼?WindowsGit指令碼
- 如何在阿里雲上執行SAP UI5應用阿里UI
- 如何在Mac上執行修復Safari緩慢的問題?Mac
- 如何在你的Linux機器上安裝執行OracleLinuxOracle
- win10執行紅警2步驟_如何在win10上執行紅警2Win10
- Flutter是如何在iOS上執行起來的原始碼解讀FlutteriOS原始碼
- [譯] 如何在遠端伺服器上執行 Jupyter Notebooks伺服器
- 打破平臺限制,小程式如何在硬體裝置上執行?
- 如何在oracle10g上檢視sql的執行計劃(不實際執行語句)OracleSQL
- 在android上執行的數學工具軟體Maxima On AndroidAndroid
- 如何在Android上播放swf檔案Android
- 如何在 Java 11 下執行 RocketMQJavaMQ
- 教你如何在Golang中執行JavaScriptGolangJavaScript
- Android上執行cocos2d-x專案Android
- 如何在mac本上安裝android sdkMacAndroid
- 如何在 Linux 上執行命令前臨時清空 Bash 環境變數Linux變數
- 同步容器(如Vector)並不是所有操作都執行緒安全!~執行緒
- Android : 執行緒的結束,掛起和恢復(上)Android執行緒
- 如何在多區域執行Zookeeper?- Ankur
- 如何在子執行緒中更新UI執行緒UI
- 如何在生產環境執行容器
- GCD延遲執行如何在中途取消GC
- 如何在Docker容器中執行GUI程式DockerGUI
- Android多執行緒之執行緒池Android執行緒
- Android的執行緒和執行緒池Android執行緒
- 程式執行緒篇——執行緒切換(上)執行緒
- 新年新語言 - ClojureScript
- 執行緒池如何觀測?這個方案讓你對執行緒池的執行情況瞭如指掌!執行緒
- Android Animation 執行原理Android
- Android執行緒池Android執行緒
- 無需 root 實現在 Android 裝置上執行 LinuxAndroidLinux