本篇文章帶大家了解一下vscode如何進(jìn)行安卓開發(fā)?希望對(duì)需要的朋友有所幫助!
vs code 大部分是由 ts 編寫,上層 UI 可以運(yùn)行在各個(gè)系統(tǒng)的瀏覽器中,但 vs code 基于 electron 框架,這個(gè)框架提供了對(duì) node 的支持,一些瀏覽器內(nèi)核中的 js 引擎沒有的 api,例如 I/O,系統(tǒng)內(nèi)核的一些交互等。而 code-server 則是解決了脫離 electron 的問題。目前安卓上有一個(gè)叫 aid learing 的軟件,自帶 VS Code ,看了一下原理差不多,并不是 linux 圖形界面打開的 VS Code,也是打開的 webview 連接本地的服務(wù),但這個(gè)玩意占磁盤內(nèi)存太高,整個(gè)下載安裝完就干掉6個(gè)g。【推薦學(xué)習(xí):《vscode》】
客戶端框架
客戶端是用 Flutter 進(jìn)行的開發(fā),而這個(gè)框架的選用并不是為了跨端,僅僅是為了快速嘗試,還有基礎(chǔ)能力的使用。
實(shí)現(xiàn)方法分析
code-server 在 github 發(fā)布的版本中是有 arm64 架構(gòu)的,整個(gè)下載后,開終端解壓執(zhí)行就掛了,這個(gè)雖然是 arm64,并且?guī)в幸粋€(gè) arm64 的 node,但是是為完整 linux 準(zhǔn)備的。也就是說,node 中硬編碼了 /usr /lib 等這些路徑,并且附帶的 node_modules 中也有大量的使用到 linux 特有節(jié)點(diǎn)的路徑,這些安卓上都沒有。 后來一想,termux 中自帶的環(huán)境也是有 libllvm gcc nodejs 的,把整個(gè) node_mudules 一刪,再手動(dòng) install 一下,就行了。 所以整個(gè)流程大致分為兩類。
初始嘗試方案:非完整Linux
-
啟動(dòng) termux 環(huán)境
-
安裝 node,python,libllvm,clang
-
下載 code-server arm64,解壓
-
處理兼容,刪除 node_modules ,重新 yarn install
-
執(zhí)行 bin/code-server 啟動(dòng)服務(wù)
經(jīng)過一些測(cè)試發(fā)現(xiàn),這種模式有一些問題。
- 下載的依賴太多,由于源都在我的個(gè)人服務(wù)器,會(huì)下很久。
- 編譯太久,yarn install 的時(shí)候調(diào)用了 gcc 的編譯,整個(gè)過程特別耗時(shí)。
- 啟動(dòng)的 vs code 用不了搜索代碼(正常情況能支持這個(gè)功能)
- 磁盤占用太大,一陣操作下來,直接1.6g磁盤空間給干沒了,主要是 npm install 拉了很多東西,還生成了一堆緩存,node_modules 嘛,比黑洞還重的東西。
不過按照以上的流程過一遍后,code-server 內(nèi)的 node_modules 已經(jīng)是安卓 arm64 可用的模塊了,二次打包 code-server,流程就可以簡(jiǎn)化成如下
-
啟動(dòng) termux 環(huán)境
-
安裝 node
-
下載 code-server arm64,解壓
-
執(zhí)行 bin/code-server
但還是會(huì)存在編輯器無法搜索代碼的 bug,node 雖然只有 20m ,但還是在個(gè)人服務(wù)器,下行帶寬 5mb,大概 700kb/s ,emmm,要集成到 apk 內(nèi)的話,得集成 deb ,調(diào) dpkg 去安裝,放棄。
最后使用方案:完整Linux
-
啟動(dòng) termux 環(huán)境
-
下載并安裝完整 Linux(30m)
-
下載 code-server arm64(自帶node能用了)
-
執(zhí)行 bin/code-server 啟動(dòng)服務(wù)
最終是選用了完整 Linux 的方式,除了安裝需要的體積更小之外,還有完整源的支持,異常 bug 的避免等。 由于整個(gè) VS Code 的啟動(dòng)需要的 130mb 的內(nèi)存都是第一次打開需要的,所以將這些內(nèi)存的占用放到服務(wù)器上,由 app 啟動(dòng)再下載的意義并不大,最后就全都作為資源文件集成到了 apk 內(nèi)。
具體實(shí)現(xiàn)
啟動(dòng) termux 環(huán)境
這個(gè)過程之前有現(xiàn)成的輪子了,只需要按照 termux-package 的編譯腳本編譯一個(gè) bootstrap 集成到 apk,app 啟動(dòng)進(jìn)行解壓,然后根據(jù)符號(hào)鏈接格式進(jìn)行恢復(fù)就行。 終端是 vscode。
bootstrap 是一個(gè)帶有最小依賴的類 linux 環(huán)境,有bash,apt 等。
具體實(shí)現(xiàn)代碼
function?initApp(){ ??cd?${RuntimeEnvir.usrPath}/ ??echo?準(zhǔn)備符號(hào)鏈接... ??for?line?in?`cat?SYMLINKS.txt` ??do ????OLD_IFS="$IFS" ????IFS="←" ????arr=($line) ????IFS="$OLD_IFS" ????ln?-s?${arr[0]}?${arr[3]} ??done ??rm?-rf?SYMLINKS.txt ??TMPDIR=/data/data/com.nightmare.termare/files/usr/tmp ??filename=bootstrap ??rm?-rf?"$TMPDIR/$filename*" ??rm?-rf?"$TMPDIR/*" ??chmod?-R?0777?${RuntimeEnvir.binPath}/* ??chmod?-R?0777?${RuntimeEnvir.usrPath}/lib/*?2>/dev/null ??chmod?-R?0777?${RuntimeEnvir.usrPath}/libexec/*?2>/dev/null ??apt?update ??rm?-rf?$lockFile ??export?LD_PRELOAD=${RuntimeEnvir.usrPath}/lib/libtermux-exec.so ??install_vs_code ??start_vs_code ??bash }
RuntimeEnvir.usrPath 是 /data/data/$package/files/usr/bin
安裝完整 Linux 和 code-server
這個(gè)我從好幾個(gè)方案進(jìn)行了篩選,起初用的 atlio 這個(gè)開源,整個(gè)開源依賴 python,并且有一個(gè)requirement.txt ,需要執(zhí)行 python -r requirement.txt,依賴就是一大堆,后來換了 proot-distro,純 shell,所以只需要直接集成到 apk 內(nèi)就行。
1.安裝 ubuntu
install_ubuntu(){ cd ~ colorEcho - 安裝Ubuntu Linux unzip proot-distro.zip >/dev/null #cd ~/proot-distro bash ./install.sh apt-get install -y proot proot-distro install ubuntu echo '$source' > $ubuntuPath/etc/apt/sources.list }
2.安裝 code-server
install_vs_code(){ ??if?[?!?-d?"$ubuntuPath/home/code-server-$version-linux-arm64"?];then ????cd?$ubuntuPath/home ????colorEcho?-?解壓?Vs?Code?Arm64 ????tar?zxvf?~/code-server-$version-linux-arm64.tar.gz?>/dev/null ????cd?code-server-$version-linux-arm64 ??fi }
啟動(dòng) code-server
直接用 proot-distro 啟動(dòng)就行,非常方便
–termux-home 參數(shù):開啟 app 沙盒的 home 掛載到 ubuntu 的 /root 下,這樣 ubuntu 就能用 app 里面的文件夾了。
start_vs_code(){ ??install_vs_code ??mkdir?-p?$ubuntuPath/root/.config/code-server?2>/dev/null ??echo?' ??bind-addr:?0.0.0.0:8080 ??auth:?none ??password:?none ??cert:?false ??'?>?$ubuntuPath/root/.config/code-server/config.yaml ??echo?-e?"x1b[31m-?啟動(dòng)中..x1b[0m" ??proot-distro?login?ubuntu?--?/home/code-server-$version-linux-arm64/bin/code-server }
其實(shí)整個(gè)實(shí)現(xiàn)其實(shí)是沒啥難度的,全都是一些 shell 腳本,也是得益于之前的 vscode 系列的支持,有興趣的可以看下這個(gè)組織。 然后就是打開 webview 的過程了,如果覺得性能不好,你可以用局域網(wǎng)的電腦來進(jìn)行連接。 看一下非首次的啟動(dòng)過程
WebView 實(shí)現(xiàn)方案
首先去 pub 看了一下 webview 的插件,官方目前正在維護(hù)的 webview 有這樣的提示
- Hybrid composition mode has a built-in keyboard support while Virtual displays mode has multiple keyboard issues
- Hybrid composition mode requires Android SKD 19+ while Virtual displays mode requires Android SDK 20+
- Hybrid composition mode has performence limitations when working on Android versions prior to Android 10 while Virtual displays is performant on all supported Android versions
也就是說開啟 hybird 后,安卓10以下有性能限制,而使用虛擬顯示器的話,鍵盤問題會(huì)很多。
實(shí)際嘗試的時(shí)候,OTG 連接的鍵盤基本是沒法用的。
再分析了下這個(gè)場(chǎng)景,最后還是用的原生 WebView,這里有些小坑。
必須啟用項(xiàng)
????????WebSettings?mWebSettings?=?mWebView.getSettings();????????//允許使用JS ????????mWebSettings.setJavaScriptEnabled(true); ????????mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true); ????????mWebSettings.setUseWideViewPort(true); ????????mWebSettings.setAllowFileAccess(true);????????//?下面這行不寫不得行 ????????mWebSettings.setDomStorageEnabled(true); ????????mWebSettings.setDatabaseEnabled(true); ????????mWebSettings.setAppCacheEnabled(true); ????????mWebSettings.setLoadWithOverviewMode(true); ????????mWebSettings.setDefaultTextEncodingName("utf-8"); ????????mWebSettings.setLoadsImagesAutomatically(true); ????????mWebSettings.setSupportMultipleWindows(true);
路由重定向
有些場(chǎng)景 VS Code 會(huì)打開一個(gè)新的窗口,例如點(diǎn)擊 file -> new window 的時(shí)候,不做處理,webview 會(huì)調(diào)起系統(tǒng)的瀏覽器。
????????//系統(tǒng)默認(rèn)會(huì)通過手機(jī)瀏覽器打開網(wǎng)頁,為了能夠直接通過WebView顯示網(wǎng)頁,必須設(shè)置 ????????mWebView.setWebViewClient(new?WebViewClient()?{ ????????????@Override ????????????public?boolean?shouldOverrideUrlLoading(WebView?view,?String?url)?{ ????????????????//使用WebView加載顯示url ????????????????view.loadUrl(url); ????????????????//返回true ????????????????return?true; ????????????} ????????});
瀏覽器正常跳轉(zhuǎn)
例如終端輸出了 vscode + 鼠標(biāo)點(diǎn)擊,預(yù)期是會(huì)打開瀏覽器的。
mWebView.setWebChromeClient(webChromeClient); WebChromeClient?webChromeClient?=?new?WebChromeClient()?{ ????????@Override ????????public?boolean?onCreateWindow(WebView?view,?boolean?isDialog,?boolean?isUserGesture,?Message?resultMsg)?{ ????????????WebView?childView?=?new?WebView(context);//Parent?WebView?cannot?host?it's?own?popup?window. ????????????childView.setBackgroundColor(Color.GREEN); ????????????childView.setWebViewClient(new?WebViewClient()?{ ????????????????@Override ????????????????public?boolean?shouldOverrideUrlLoading(WebView?view,?String?url)?{ ????????????????????context.startActivity(new?Intent(Intent.ACTION_VIEW,?Uri.parse(url))); ????????????????????return?true; ????????????????} ????????????}); ????????????WebView.WebViewTransport?transport?=?(WebView.WebViewTransport)?resultMsg.obj; ????????????transport.setWebView(childView);//setWebView和getWebView兩個(gè)方法 ????????????resultMsg.sendToTarget(); ????????????return?true; ????????} ????};
可行性探索
這個(gè)能干嘛?安卓屏幕那么小,電腦能本地用 vscode 干嘛要連安卓的?
- 有一個(gè) vs code 加一個(gè)完整的 linux 環(huán)境,能 cover 住一些場(chǎng)景的開發(fā)了,安卓開發(fā)等除外。
- 開發(fā)程序到 arm 板子的同學(xué),PC 上還得弄一堆交叉編譯工具鏈,并且每次編譯調(diào)試過程也很繁瑣,現(xiàn)在就能本地寫本地編譯。
正巧,買了一個(gè)平板,愛奇藝之余,也能作為程序員的一波生產(chǎn)力了。
編譯 C 語言
選了一個(gè)一直在學(xué)習(xí)的項(xiàng)目,scrcpy,一堆 c 源碼,最后很順利的編譯下來了。
Web 開發(fā)
移動(dòng)端的網(wǎng)頁調(diào)試一直都是問題,作為野路子前端的我也很無奈,一般會(huì)加一些 vconsole 的組件來獲取調(diào)試日志。
之前個(gè)人項(xiàng)目速享適配移動(dòng)端 web 就是這么干的
現(xiàn)在,我們可以本地開發(fā),本地調(diào)試,有 node 整個(gè)前端大部分項(xiàng)目都能拉下來了,真實(shí)的移動(dòng)端物理環(huán)境。 試試
寫博客
本篇文章完全是在這個(gè)安卓版的 VS Code 中完成的,使用 hexo 本地調(diào)式
寫文檔
寫后臺(tái),接口測(cè)試
寫一點(diǎn)簡(jiǎn)單的后臺(tái),如 python 的 fastapi,flask,并通過 rest client 進(jìn)行接口測(cè)試
最后
為了讓其他的用戶能直接使用到這個(gè) app,我將其上架到了酷安。
看了下 vscodium 和 code-server 的開源協(xié)議都是 MIT,如果有侵權(quán)的地方辛苦評(píng)論區(qū)提醒一下鄙人。
隨便玩,有問題評(píng)論區(qū)留言,覺得不錯(cuò)的給個(gè) star,文章不錯(cuò)的給個(gè)贊,