信UOS上編譯內(nèi)核跑Anbox:從binder配置到APK安裝完整指南)
我最近在一臺(tái)統(tǒng)信UOS系統(tǒng)的機(jī)器上完整走了一遍Anbox路線從內(nèi)核編譯到安卓APP裝進(jìn)系統(tǒng)中間踩了不少Linux發(fā)行版特有的坑。老實(shí)說(shuō)UOS雖然和Debian系沾親帶故但它在內(nèi)核、安全中心、軟件源這幾個(gè)環(huán)節(jié)都有自己的脾氣網(wǎng)上大量Ubuntu教程直接照搬過(guò)來(lái)大概率會(huì)卡在“模塊加載”或“服務(wù)起不來(lái)”這種地方。這篇就把整個(gè)過(guò)程記錄下來(lái)把容易踩坑的關(guān)鍵點(diǎn)都指出來(lái)給想在UOS上跑安卓APP的朋友一條能直接照著做的路。說(shuō)一下適用范圍如果你需要的是偶爾運(yùn)行辦公、工具類、輕娛樂(lè)的安卓APP那Anbox性價(jià)比很高如果你指望它變成第二個(gè)安卓手機(jī)那我建議降低預(yù)期。文章按“選型思路 → 內(nèi)核準(zhǔn)備 → 內(nèi)核編譯 → 模塊驗(yàn)證 → Anbox安裝 → APK安裝”的順序?qū)懨恳徊阶隽耸裁?、為什么這么做、出問(wèn)題怎么查都會(huì)說(shuō)清楚。1. UOS跑安卓應(yīng)用的方案對(duì)比為什么我最后選了Anbox1.1 模擬器、容器、原生方案的本質(zhì)差異在UOS上跑安卓APP大致有三條路虛擬機(jī)模擬器、容器方案、閉源的商業(yè)兼容層。后面這類在UOS上不夠通用我身邊用的人不多這里主要說(shuō)前兩者。模擬器方案以VirtualBox或QEMU為代表在宿主機(jī)里虛擬出一整套硬件再在虛擬硬件上跑完整的Android系統(tǒng)。優(yōu)點(diǎn)是兼容性最好幾乎什么APK都能裝缺點(diǎn)是性能損耗明顯內(nèi)存和CPU開(kāi)銷都大UOS又是出了名的吃內(nèi)存日常體驗(yàn)容易卡頓適合測(cè)試不適合常駐使用。容器方案以Anbox和Waydroid為代表它們不虛擬硬件而是直接復(fù)用宿主機(jī)的Linux內(nèi)核把Android的用戶態(tài)裝進(jìn)隔離環(huán)境里運(yùn)行。因?yàn)闆](méi)有硬件模擬層啟動(dòng)速度快、性能接近原生但對(duì)“宿主機(jī)內(nèi)核能提供什么能力”有硬性要求最典型的就是內(nèi)核必須提供Android所需的binder和ashmem這兩類IPC/內(nèi)存設(shè)備。我的最終選擇是Anbox原因有兩點(diǎn)一是它對(duì)內(nèi)核的要求在UOS 5.10內(nèi)核上可以通過(guò)自行編譯實(shí)現(xiàn)路徑清晰二是它的社區(qū)資料相對(duì)穩(wěn)定官方deb包在Debian系上安裝也流暢。Waydroid雖然更新、Android版本也新但它的binderfs依賴在UOS上更容易出問(wèn)題后文會(huì)展開(kāi)說(shuō)。1.2 Anbox的邊界哪些APP裝得起哪些裝了也白搭選型之前先聊清楚邊界問(wèn)題否則后面裝完再后悔就晚了。Anbox官方鏡像基于Android 7這個(gè)版本本身不算高再加上鏡像里沒(méi)有Google Mobile ServicesGMS所以會(huì)遇到這些情況依賴Google服務(wù)框架的APP比如大量國(guó)外社交、地圖、支付類APP裝了大概率閃退或卡在啟動(dòng)頁(yè)。比較新的國(guó)產(chǎn)APP如果最低支持版本高于Android 7會(huì)直接提示“無(wú)法安裝”或“解析包錯(cuò)誤”。純ARM架構(gòu)的APK在Anbox默認(rèn)的x86_64鏡像里沒(méi)法直接跑需要找x86/x86_64版本。硬件GPS、NFC這類設(shè)備功能基本指望不上因?yàn)锳nbox只提供基礎(chǔ)的虛擬傳感器和網(wǎng)絡(luò)。換句話說(shuō)Anbox最適合的場(chǎng)景是在辦公電腦上跑一個(gè)需要安卓環(huán)境才能用的輕量工具APP比如某個(gè)設(shè)備管理工具、某個(gè)內(nèi)部OA、某個(gè)常用的文件處理工具。如果你要玩王者榮耀、原神這種3D大作就不要折騰Anbox了。1.3 我為什么沒(méi)選WaydroidWaydroid這幾年風(fēng)頭很足支持較新的Android容器圖形性能也更好按理說(shuō)比Anbox有前途。但我在UOS上實(shí)測(cè)下來(lái)的感覺(jué)是它的官方腳本對(duì)Debian系的支持比較粗糙而且Waydroid依賴binderfs而UOS自帶內(nèi)核默認(rèn)沒(méi)有開(kāi)啟binderfs這意味著很可能需要自己編譯內(nèi)核或加載額外模塊。既然怎么都要碰內(nèi)核那選配置路徑更成熟、社區(qū)資料更明確的Anbox反而省心。我這不是說(shuō)Waydroid不行而是“在UOS上從零跑通”這個(gè)前提下Anbox的坑更少、更可控。后面所有內(nèi)容都圍繞Anbox展開(kāi)。2. 編譯內(nèi)核前的準(zhǔn)備工作版本確認(rèn)、工具鏈和源碼獲取2.1 先搞清楚你手上這臺(tái)UOS的底細(xì)不要憑感覺(jué)開(kāi)始第一步永遠(yuǎn)是確認(rèn)系統(tǒng)情況。我會(huì)按下面幾條命令過(guò)一遍cat /etc/os-release uname -r uname -m我手頭這臺(tái)是UOS 20系列內(nèi)核版本5.10.xx86_64架構(gòu)。如果你的內(nèi)核版本是4.19或者更新的5.15后面配置項(xiàng)的寫(xiě)法會(huì)略有差異但整體流程一致。這里特別強(qiáng)調(diào)一點(diǎn)編譯內(nèi)核最好選擇和當(dāng)前系統(tǒng)版本接近的內(nèi)核源碼不要一上來(lái)就拉Linux主線最新版。主線內(nèi)核和UOS深度定制的內(nèi)核差異太大就算Anbox跑起來(lái)了顯卡驅(qū)動(dòng)、指紋驅(qū)動(dòng)、電源管理等很可能翻車得不償失。2.2 編譯工具鏈和依賴庫(kù)的坑UOS默認(rèn)桌面版不會(huì)裝全套編譯工具需要手動(dòng)補(bǔ)上sudo apt update sudo apt install build-essential bc bison flex libssl-dev libelf-dev dwarves這幾個(gè)包的作用分別是build-essential提供gcc和make基礎(chǔ)環(huán)境bc是內(nèi)核配置腳本用的計(jì)算器工具bison和flex用來(lái)處理內(nèi)核源碼里的語(yǔ)法解析器libssl-dev負(fù)責(zé)內(nèi)核模塊簽名和加密相關(guān)功能libelf-dev和dwarves主要是新版內(nèi)核生成BTF信息時(shí)需要用的不裝的話編譯到最后可能報(bào)錯(cuò)。有個(gè)UOS特有的小坑dwarves這個(gè)包在部分UOS源里叫pahole如果你執(zhí)行上面命令時(shí)報(bào)“無(wú)法定位軟件包”先搜一下apt search pahole把包名替換一下即可。2.3 內(nèi)核源碼從哪里來(lái)用什么版本最穩(wěn)獲取UOS內(nèi)核源碼我個(gè)人推薦三種方式按優(yōu)先級(jí)排列如果軟件源里開(kāi)了deb-src直接apt-get source拉取當(dāng)前版本源碼和系統(tǒng)默認(rèn)配置最貼近。從統(tǒng)信/Deepin的開(kāi)源倉(cāng)庫(kù)下載與當(dāng)前內(nèi)核版本一致的源碼包這種方式最穩(wěn)我最后也是走的這條路。實(shí)在找不到匹配版本再去kernel.org下載相同大版本號(hào)的官方內(nèi)核但需要手動(dòng)把UOS的編譯配置遷移過(guò)去過(guò)程繁瑣不推薦新手嘗試。源碼準(zhǔn)備好之后把當(dāng)前系統(tǒng)內(nèi)核的配置文件拷貝出來(lái)作為基礎(chǔ)配置cp /boot/config-$(uname -r) .config這一步能讓你在后續(xù)編譯時(shí)沿用UOS默認(rèn)的硬件支持、文件系統(tǒng)、驅(qū)動(dòng)選項(xiàng)只針對(duì)Anbox需要的功能做增量修改大幅降低“編譯完新內(nèi)核導(dǎo)致無(wú)線網(wǎng)卡失效、顯卡出問(wèn)題”的風(fēng)險(xiǎn)。3. 內(nèi)核配置與編譯實(shí)操把binder和ashmem放進(jìn)來(lái)3.1 binder和ashmem到底在Anbox里扮演什么角色Anbox復(fù)用宿主機(jī)內(nèi)核但Android的用戶態(tài)代碼并不認(rèn)識(shí)普通Linux內(nèi)核它只認(rèn)Android內(nèi)核提供的幾個(gè)專屬設(shè)備。其中最關(guān)鍵的是兩個(gè)binderAndroid系統(tǒng)的進(jìn)程間通信中樞。Android里APP和系統(tǒng)服務(wù)之間幾乎所有的跨進(jìn)程調(diào)用都要經(jīng)過(guò)binder相當(dāng)于一個(gè)“系統(tǒng)級(jí)服務(wù)臺(tái)”。沒(méi)有它Android的各個(gè)進(jìn)程之間沒(méi)法通信系統(tǒng)服務(wù)起不來(lái)整個(gè)環(huán)境自然就崩了。ashmem匿名共享內(nèi)存機(jī)制用來(lái)在進(jìn)程之間高效傳遞大塊數(shù)據(jù)。圖形緩沖、進(jìn)程間大數(shù)據(jù)交換都依賴它你可以理解成“進(jìn)程們共用的倉(cāng)庫(kù)”。Anbox啟動(dòng)時(shí)容器里的Android系統(tǒng)會(huì)直接去打開(kāi)/dev/binder和/dev/ashmem這兩個(gè)設(shè)備節(jié)點(diǎn)。設(shè)備不存在、權(quán)限不夠、模塊版本不匹配任何一個(gè)環(huán)節(jié)出問(wèn)題都會(huì)導(dǎo)致啟動(dòng)失敗或中途崩潰。3.2 打開(kāi)配置項(xiàng)從基礎(chǔ)config到olddefconfig拿到基礎(chǔ)的.config文件后用內(nèi)核源碼自帶的配置腳本直接修改配置項(xiàng)比打開(kāi)menuconfig一個(gè)個(gè)找要快得多也更容易寫(xiě)到教程里復(fù)現(xiàn)cd /path/to/kernel-source # 打開(kāi)Android相關(guān)支持和兩個(gè)關(guān)鍵設(shè)備驅(qū)動(dòng) scripts/config --enable CONFIG_ANDROID scripts/config --enable CONFIG_ANDROID_BINDER_IPC scripts/config --enable CONFIG_ASHMEM # 生成最終的完整配置文件 make olddefconfig這三個(gè)是Anbox跑起來(lái)的最低要求。CONFIG_ANDROID是Android內(nèi)核支持的總開(kāi)關(guān)CONFIG_ANDROID_BINDER_IPC對(duì)應(yīng)binder驅(qū)動(dòng)CONFIG_ASHMEM對(duì)應(yīng)ashmem驅(qū)動(dòng)。用--enable選項(xiàng)會(huì)把選項(xiàng)編譯進(jìn)內(nèi)核而不是編譯成外部模塊這樣重啟之后設(shè)備節(jié)點(diǎn)就會(huì)自動(dòng)出現(xiàn)省去手動(dòng)modprobe的麻煩我強(qiáng)烈建議用這種方式。至于CONFIG_ANDROID_BINDERFS這是新版內(nèi)核引入的binder文件系統(tǒng)機(jī)制Anbox社區(qū)對(duì)它的支持并不統(tǒng)一默認(rèn)可以不開(kāi)啟。如果你以后要用Waydroid可以再回頭編譯一個(gè)帶binderfs的新內(nèi)核當(dāng)前階段不要給自己增加變量。配置改完之后用以下命令確認(rèn)關(guān)鍵選項(xiàng)確實(shí)打開(kāi)了grep -E CONFIG_ANDROID|CONFIG_ASHMEM|CONFIG_BINDER .config只要看到對(duì)應(yīng)選項(xiàng)后面跟著y而不是# CONFIG_XX is not set就說(shuō)明配置生效了。3.3 編譯與打包用deb包方式安裝內(nèi)核編譯內(nèi)核有兩種常見(jiàn)姿勢(shì)一種是在源碼目錄里直接make install和make modules_install另一種是用make deb-pkg打成deb包再安裝。我強(qiáng)烈建議用deb包方式make -j $(nproc) deb-pkg-j參數(shù)后面接CPU核心數(shù)如果你的機(jī)器內(nèi)存足夠可以稍微加大一點(diǎn)并行度。編譯過(guò)程根據(jù)CPU性能不同通常要等20分鐘到1小時(shí)不等。正常情況下編譯完成后會(huì)在源碼目錄的上一級(jí)目錄生成類似linux-image-5.10.x_*.deb、linux-headers-5.10.x_*.deb、linux-libc-dev_*.deb的安裝包。然后用dpkg -i逐個(gè)安裝sudo dpkg -i ../linux-image-*.deb ../linux-headers-*.deb ../linux-libc-dev_*.deb sudo update-grub2完成后重啟機(jī)器。用deb包方式有幾個(gè)好處一是安裝路徑和UOS默認(rèn)內(nèi)核一致grub能自動(dòng)識(shí)別二是哪天新內(nèi)核出問(wèn)題了還能在grub啟動(dòng)菜單里選擇老內(nèi)核回滾三是不用擔(dān)心手動(dòng)make install把/lib/modules目錄搞亂。4. 模塊加載與驗(yàn)證編譯完不等于能用4.1 重啟后先驗(yàn)證設(shè)備節(jié)點(diǎn)重啟后第一件事確認(rèn)當(dāng)前確實(shí)進(jìn)入了新內(nèi)核uname -r如果版本號(hào)對(duì)上了接下來(lái)直接看設(shè)備節(jié)點(diǎn)ls -l /dev/binder /dev/ashmem因?yàn)槲仪懊嬗玫氖?-enable編譯進(jìn)內(nèi)核正常情況這里應(yīng)該能看到binder和ashmem兩個(gè)設(shè)備文件。如果看不到也不要急著繼續(xù)裝Anbox先排查清楚否則后面每一步都會(huì)出奇怪的報(bào)錯(cuò)。4.2 設(shè)備或模塊不對(duì)時(shí)的完整排查順序如果你看到設(shè)備節(jié)點(diǎn)缺失按照下面的順序排查不要跳過(guò)任何一步確認(rèn)內(nèi)核配置確實(shí)編譯進(jìn)去了。執(zhí)行zcat /proc/config.gz | grep -E BINDER|ASHMEM如果系統(tǒng)沒(méi)有開(kāi)啟/proc/config.gz那就回到源碼目錄用grep查.config文件。檢查模塊文件是否存在。有些情況下雖然配置開(kāi)了但被編成了外部模塊m那就需要手動(dòng)加載find /lib/modules/$(uname -r) -name *binder* -o -name *ashmem*找到對(duì)應(yīng)的.ko文件后modprobe加載。模塊名在不同內(nèi)核里不完全一樣5.10上常見(jiàn)的是binder_linux和ashmem_linux4.19上則更可能是binder和ashmem一切以實(shí)際文件名稱為準(zhǔn)。查看內(nèi)核是否注冊(cè)了misc設(shè)備。binder和ashmem驅(qū)動(dòng)在misc設(shè)備框架下注冊(cè)加載成功后會(huì)出現(xiàn)在/proc/misc里cat /proc/misc | grep -E binder|ashmem如果模塊在、設(shè)備節(jié)點(diǎn)卻沒(méi)有手動(dòng)創(chuàng)建設(shè)備文件也只是臨時(shí)方案。先用cat /proc/misc | grep binder查到binder對(duì)應(yīng)的次設(shè)備號(hào)假設(shè)查到的是57再執(zhí)行sudo mknod /dev/binder c 10 57 sudo chmod 0666 /dev/binder要注意的是misc設(shè)備的主設(shè)備號(hào)通常是10但次設(shè)備號(hào)是內(nèi)核運(yùn)行時(shí)動(dòng)態(tài)分配的不同機(jī)器可能不一樣不要照抄網(wǎng)上的“57”。這也是為什么強(qiáng)烈建議把驅(qū)動(dòng)編譯進(jìn)內(nèi)核而不是加載模塊前者能觸發(fā)自動(dòng)創(chuàng)建節(jié)點(diǎn)后者則可能遇到udev沒(méi)有自動(dòng)生成節(jié)點(diǎn)的尷尬。4.3 用模塊加載配置和udev規(guī)則把權(quán)限一次做對(duì)設(shè)備節(jié)點(diǎn)創(chuàng)建出來(lái)只是第一步還要確保每次開(kāi)機(jī)都自動(dòng)生效、并且當(dāng)前用戶有權(quán)限訪問(wèn)。創(chuàng)建/etc/modules-load.d/anbox.conf文件內(nèi)容寫(xiě)上模塊名binder_linux ashmem_linux如果你的模塊被編譯成binder和ashmem的舊命名文件名對(duì)應(yīng)改成這兩個(gè)名字就行。這一步只對(duì)“模塊方式”有意義編譯進(jìn)內(nèi)核的系統(tǒng)理論上不需要但寫(xiě)上也無(wú)妨不會(huì)影響啟動(dòng)。接下來(lái)是udev規(guī)則把設(shè)備權(quán)限放開(kāi)。創(chuàng)建/etc/udev/rules.d/99-anbox.rulesKERNELbinder, NAMEbinder, MODE0666 KERNELashmem, NAMEashmem, MODE0666然后重新加載規(guī)則sudo udevadm control --reload-rules sudo udevadm trigger這一步特別容易被忽略。Anbox的容器服務(wù)是root啟動(dòng)的沒(méi)問(wèn)題但圖形界面的session-manager通常以普通用戶身份運(yùn)行如果設(shè)備權(quán)限是root:root 0644普通用戶打開(kāi)/dev/binder就會(huì)報(bào)Permission denied而且報(bào)錯(cuò)信息不會(huì)直接說(shuō)“沒(méi)權(quán)限”而是“無(wú)法啟動(dòng)Android系統(tǒng)”誤導(dǎo)性很強(qiáng)。5. Anbox本機(jī)安裝deb包、源碼構(gòu)建和依賴排錯(cuò)5.1 安裝Anbox先走官方deb包這條路內(nèi)核就緒后開(kāi)始裝Anbox本體。建議直接從Anbox官方GitHub倉(cāng)庫(kù)的Release頁(yè)面下載x86_64版本的deb包然后執(zhí)行sudo dpkg -i anbox*.deb sudo apt -f install第一次dpkg -i大概率會(huì)報(bào)依賴缺失這是預(yù)期內(nèi)的。apt -f install會(huì)自動(dòng)把缺的依賴包拉齊比如libwayland相關(guān)庫(kù)、dbus相關(guān)工具等。UOS軟件源里的包版本如果偏老個(gè)別依賴可能提示“無(wú)法滿足依賴關(guān)系”這時(shí)候可以關(guān)注一下缺的具體包名手動(dòng)疊加倉(cāng)庫(kù)或用更高版本替換。這里還要提一個(gè)UOS特有的前置條件**UOS有比較嚴(yán)格的安全中心未在應(yīng)用商店上架的deb包在安裝時(shí)可能被攔截或提示不受信來(lái)源)。建議在控制中心的“通用—開(kāi)發(fā)者模式”里按統(tǒng)信官方流程開(kāi)啟開(kāi)發(fā)者模式。這不是可有可無(wú)的操作我見(jiàn)過(guò)不少人在這一步卡住dpkg安裝了但文件被安全策略擋在外面Anbox服務(wù)怎么起都失敗。5.2 開(kāi)啟容器管理服務(wù)并檢查journalctldeb包安裝完成之后系統(tǒng)里會(huì)多出一個(gè)anbox-container-manager服務(wù)這個(gè)服務(wù)負(fù)責(zé)真正把Android的rootfs跑起來(lái)。先把它設(shè)為開(kāi)機(jī)自啟sudo systemctl enable --now anbox-container-manager systemctl status anbox-container-manager看到狀態(tài)不是active (running)先不要急著配置畫(huà)面用journalctl看日志journalctl -u anbox-container-manager -e我實(shí)測(cè)中最高頻的報(bào)錯(cuò)就幾種找不到/dev/binder、權(quán)限不夠、/var/lib/anbox下的rootfs沒(méi)有生成。前面內(nèi)核部分處理好了第一種基本不會(huì)出現(xiàn)第二種大概率是udev規(guī)則沒(méi)生效第三種則在重裝一次deb包后可以解決。容器服務(wù)正常后再啟動(dòng)圖形會(huì)話anbox session-manager 如果這一步安靜地待在后臺(tái)沒(méi)有報(bào)錯(cuò)說(shuō)明Anbox已經(jīng)成功連接上了Android系統(tǒng)。如果報(bào)錯(cuò)繼續(xù)看終端的輸出日志通常信息比systemd日志更直接。5.3 UOS安全策略對(duì)anbox的額外限制UOS的安全基線做得比普通Debian嚴(yán)格不少具體到Anbox身上我踩過(guò)的一個(gè)坑是systemd服務(wù)執(zhí)行時(shí)被設(shè)備訪問(wèn)策略擋住。日志里可能會(huì)出現(xiàn)關(guān)于DevicePolicy或類似的關(guān)鍵字這表明systemd的沙箱配置限制了容器服務(wù)訪問(wèn)設(shè)備節(jié)點(diǎn)。遇到這種情況不要急著去關(guān)UOS的安全保護(hù)可以用systemd的drop-in來(lái)針對(duì)性放行sudo systemctl edit anbox-container-manager在打開(kāi)的編輯器里根據(jù)journalctl提示的策略類型填入對(duì)應(yīng)的放開(kāi)配置保存后重啟服務(wù)。如果日志里提到了AppArmor那就單獨(dú)對(duì)anbox相關(guān)的profile使用aa-complain切換為警告模式觀察效果。其實(shí)大多數(shù)情況下根本不需要改這些安全策略問(wèn)題還是出在前面說(shuō)的設(shè)備節(jié)點(diǎn)和權(quán)限上。所以我一直強(qiáng)調(diào)先確保/dev/binder和/dev/ashmem對(duì)普通用戶都可用再去看安全策略這個(gè)順序不要顛倒。6. 把APK裝進(jìn)Anbox并真正跑起來(lái)ADB、圖形與共享目錄6.1 通過(guò)adb把APK推進(jìn)容器Anbox跑起來(lái)后最直接的安裝APK方式是ADB。UOS如果不帶adb先裝sudo apt install adb然后連接Anbox暴露出來(lái)的本地ADB端口adb connect localhost:5555 adb devices如果連接成功adb devices會(huì)顯示一臺(tái)設(shè)備。如果連接后過(guò)一會(huì)又lost大概率是sandbox和session-manager之間斷了回看第5章的日志排查。連接穩(wěn)定后安裝APK就一行命令adb install 你的應(yīng)用.apk安裝大體積APK時(shí)偶爾會(huì)遇到timeout可以把安裝方式拆開(kāi)先推送再在設(shè)備內(nèi)安裝adb push 你的應(yīng)用.apk /data/local/tmp/ adb shell pm install /data/local/tmp/你的應(yīng)用.apk這種方法比單純的adb install穩(wěn)定不少尤其是幾十MB以上的安裝包。6.2 APK架構(gòu)和Android版本帶來(lái)的兼容性限制APK裝進(jìn)去了不代表能打開(kāi)兼容性問(wèn)題是Anbox用戶最需要心理準(zhǔn)備的部分。Anbox官方鏡像是x86_64架構(gòu)的Android 7所以優(yōu)先下載x86或x86_64版本APK?,F(xiàn)在很多應(yīng)用商店默認(rèn)下發(fā)arm64包裝進(jìn)去之后啟動(dòng)時(shí)“直接閃退”或報(bào)“無(wú)法執(zhí)行二進(jìn)制文件”多半就是這個(gè)原因。依賴Google Play服務(wù)的APP基本沒(méi)戲。Anbox鏡像不帶GMS應(yīng)用只要調(diào)用了Google服務(wù)接口簡(jiǎn)單點(diǎn)的還能報(bào)個(gè)錯(cuò)復(fù)雜點(diǎn)的直接卡開(kāi)機(jī)動(dòng)畫(huà)。Android 7以下的舊應(yīng)用反而更容易兼容因?yàn)樗鼈儺?dāng)時(shí)就是照著Android 6/7的API寫(xiě)的。如果你確實(shí)需要跑一個(gè)arm64-only的應(yīng)用也可以搜索社區(qū)里針對(duì)Anbox修改的arm轉(zhuǎn)譯方案但這套方案在Android 7上的可用性一般屬于進(jìn)階玩法文章里不展開(kāi)介紹。6.3 窗口尺寸、文件傳輸和性能優(yōu)化Anbox默認(rèn)啟動(dòng)后是一個(gè)豎屏手機(jī)窗口在辦公顯示器上顯得很小。分辨率可以通過(guò)session-manager的支持參數(shù)調(diào)整不同版本參數(shù)大同小異先用anbox session-manager --help看看當(dāng)前版本支持哪些選項(xiàng)再按需設(shè)置。我自己的習(xí)慣是把它調(diào)成接近手機(jī)的中等窗口而不是強(qiáng)行拉滿全屏因?yàn)锳nbox的圖形性能上限不高拉滿只會(huì)讓畫(huà)面更卡。文件傳輸方面Anbox沒(méi)有模擬器那種“共享宿主目錄”的便利功能日常文件交換基本靠ADBadb push ./files/ /sdcard/ adb pull /sdcard/文件 ./桌面/性能優(yōu)化我提三個(gè)可行的方向。一是如果宿主機(jī)GPU驅(qū)動(dòng)較弱部分應(yīng)用會(huì)白屏或渲染異常設(shè)置環(huán)境變量LIBGL_ALWAYS_SOFTWARE1能有效避開(kāi)GPU驅(qū)動(dòng)坑代價(jià)是圖形性能進(jìn)一步下降二是在Anbox系統(tǒng)里關(guān)閉窗口動(dòng)畫(huà)安裝完應(yīng)用后執(zhí)行adb shell settings put global window_animation_scale 0 adb shell settings put global transition_animation_scale 0 adb shell settings put global animator_duration_scale 0三是如果發(fā)現(xiàn)Anbox進(jìn)程吃內(nèi)存太多可以在systemd服務(wù)的drop-in文件里加上MemoryMax限制避免它把宿主機(jī)內(nèi)存占光導(dǎo)致整個(gè)桌面露餡。性能調(diào)整沒(méi)有銀彈具體壓到什么值需要邊觀察任務(wù)管理器邊調(diào)。整套流程走完我最想強(qiáng)調(diào)的還是開(kāi)頭那句話Anbox最麻煩的從來(lái)不是Anbox本身而是它依賴的內(nèi)核能力和UOS默認(rèn)配置之間的差異。只要binder和ashmem兩個(gè)設(shè)備能在系統(tǒng)里穩(wěn)定存在、權(quán)限正確后面的container-manager、session-manager、adb install基本都會(huì)一路順利。反過(guò)來(lái)說(shuō)如果內(nèi)核這一步?jīng)]做扎實(shí)裝再多次deb包也是白搭。我在UOS上跑通這套流程之后目前最常用的場(chǎng)景是把一個(gè)老舊的設(shè)備管理工具APP放進(jìn)Anbox里日常打卡用占用很小開(kāi)機(jī)自啟后幾乎無(wú)感。如果你也用UOS當(dāng)主力桌面系統(tǒng)手上恰好有一兩個(gè)“只能在安卓上跑”的剛需應(yīng)用Anbox值得抽一個(gè)下午認(rèn)真折騰一次。內(nèi)核編譯等待的那段時(shí)間雖然枯燥但換來(lái)的是干凈、輕量、可控的安卓子環(huán)境這筆賬在辦公場(chǎng)景下是劃算的。