docker android 模擬器

背景

android 應(yīng)用開發(fā)后,會有ci和自動化測試的需求,如何將android模擬器運(yùn)行在docker上,
google 幾年前在github上發(fā)布過相關(guān)的腳本解決這個問題,https://github.com/google/android-emulator-container-scripts
本文介紹實(shí)際操作和腳本的一些含義。

操作

本文操作環(huán)境是ubuntu 20.04.3
安裝好Python
安裝好 Docker
安裝好 Docker-compose
首先clone

git clone https://github.com/google/android-emulator-container-scripts

目錄結(jié)構(gòu)如下

#ls -l
-rw-r--r-- 1 root root   157 12月 16 08:37 aemu-container.code-workspace
drwxr-xr-x 2 root root  4096 12月 16 08:37 cloud-init
-rwxr-xr-x 1 root root  1583 12月 16 08:37 configure.sh
-rw-r--r-- 1 root root  1101 12月 16 08:37 CONTRIBUTING.md
-rwxr-xr-x 1 root root  4034 12月 16 08:37 create_web_container.sh
drwxr-xr-x 4 root root  4096 12月 16 08:37 emu
drwxr-xr-x 8 root root  4096 12月 16 08:37 js
-rw-r--r-- 1 root root 11332 12月 16 08:37 LICENSE
-rw-r--r-- 1 root root    46 12月 16 08:37 MANIFEST.in
-rw-r--r-- 1 root root   164 12月 16 08:37 pyproject.toml
-rw-r--r-- 1 root root 18644 12月 16 08:37 README.md
-rw-r--r-- 1 root root  4359 12月 16 08:37 REGISTRY.MD
-rwxr-xr-x 1 root root  1440 12月 16 08:37 run-in-script-example.sh
-rwxr-xr-x 1 root root   899 12月 16 08:37 run.sh
-rwxr-xr-x 1 root root  1222 12月 16 08:37 run-with-gpu.sh
-rw-r--r-- 1 root root   781 12月 16 08:37 setup.cfg
-rw-r--r-- 1 root root  8386 12月 16 08:37 setup.py
drwxr-xr-x 3 root root  4096 12月 16 08:37 tests
-rw-r--r-- 1 root root   730 12月 16 08:37 tox.ini
-rw-r--r-- 1 root root  8553 12月 16 08:37 TROUBLESHOOTING.md
-rw-r--r-- 1 root root 68611 12月 16 08:37 versioneer.py

安裝腳本命令,該命令會創(chuàng)建Python獨(dú)立環(huán)境,同時安裝emu_docker命令,emu_docker命令本質(zhì)就是 emu_docker腳本

# source ./configure.sh
....
Ready to run emu-docker

列出可用的android系統(tǒng)鏡像和模擬器

#emu-docker list
SYSIMG K android x86 19 https://dl.google.com/android/repository/sys-img/android/x86-19_r06.zip
SYSIMG K google_apis x86 19 https://dl.google.com/android/repository/sys-img/google_apis/x86-19_r40.zip
SYSIMG L android x86 21 https://dl.google.com/android/repository/sys-img/android/x86-21_r05.zip
SYSIMG L android-tv x86 21 https://dl.google.com/android/repository/sys-img/android-tv/x86-21_r03.zip
SYSIMG L google_apis x86 21 https://dl.google.com/android/repository/sys-img/google_apis/x86-21_r32.zip
SYSIMG L android x86 22 https://dl.google.com/android/repository/sys-img/android/x86-22_r06.zip
SYSIMG L android-tv x86 22 https://dl.google.com/android/repository/sys-img/android-tv/x86-22_r03.zip
SYSIMG L google_apis x86 22 https://dl.google.com/android/repository/sys-img/google_apis/x86-22_r26.zip
SYSIMG M android x86 23 https://dl.google.com/android/repository/sys-img/android/x86-23_r10.zip
SYSIMG M android-tv x86 23 https://dl.google.com/android/repository/sys-img/android-tv/x86-23_r21.zip
SYSIMG M google_apis x86 23 https://dl.google.com/android/repository/sys-img/google_apis/x86-23_r33.zip
SYSIMG N android x86 24 https://dl.google.com/android/repository/sys-img/android/x86-24_r08.zip
SYSIMG N android-tv x86 24 https://dl.google.com/android/repository/sys-img/android-tv/x86-24_r22.zip
SYSIMG N google_apis x86 24 https://dl.google.com/android/repository/sys-img/google_apis/x86-24_r27.zip
SYSIMG N google_apis_playstore x86 24 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-24_r19.zip
SYSIMG N android x86 25 https://dl.google.com/android/repository/sys-img/android/x86-25_r01.zip
SYSIMG N android-tv x86 25 https://dl.google.com/android/repository/sys-img/android-tv/x86-25_r16.zip
SYSIMG N google_apis x86 25 https://dl.google.com/android/repository/sys-img/google_apis/x86-25_r18.zip
SYSIMG N google_apis_playstore x86 25 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-25_r09.zip
SYSIMG O android x86_64 26 https://dl.google.com/android/repository/sys-img/android/x86_64-26_r01.zip
SYSIMG O android x86 26 https://dl.google.com/android/repository/sys-img/android/x86-26_r01.zip
SYSIMG O android-tv x86 26 https://dl.google.com/android/repository/sys-img/android-tv/x86-26_r14.zip
SYSIMG O google_apis x86_64 26 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-26_r16.zip
SYSIMG O google_apis x86 26 https://dl.google.com/android/repository/sys-img/google_apis/x86-26_r16.zip
SYSIMG O google_apis_playstore x86 26 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-26_r07.zip
SYSIMG O android x86_64 27 https://dl.google.com/android/repository/sys-img/android/x86_64-27_r01.zip
SYSIMG O android x86 27 https://dl.google.com/android/repository/sys-img/android/x86-27_r01.zip
SYSIMG O android-tv x86 27 https://dl.google.com/android/repository/sys-img/android-tv/x86-27_r09.zip
SYSIMG O google_apis x86 27 https://dl.google.com/android/repository/sys-img/google_apis/x86-27_r11.zip
SYSIMG O google_apis_playstore x86 27 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-27_r03.zip
SYSIMG P android x86_64 28 https://dl.google.com/android/repository/sys-img/android/x86_64-28_r04.zip
SYSIMG P android x86 28 https://dl.google.com/android/repository/sys-img/android/x86-28_r04.zip
SYSIMG P android-tv x86 28 https://dl.google.com/android/repository/sys-img/android-tv/x86-28_r10.zip
SYSIMG P google_apis x86_64 28 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-28_r11.zip
SYSIMG P google_apis x86 28 https://dl.google.com/android/repository/sys-img/google_apis/x86-28_r12.zip
SYSIMG P google_apis_playstore x86_64 28 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-28_r08.zip
SYSIMG P google_apis_playstore x86 28 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-28_r08.zip
SYSIMG P google_apis_playstore x86 28 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-28_r09.zip
SYSIMG Q android x86_64 29 https://dl.google.com/android/repository/sys-img/android/x86_64-29_r08-linux.zip
SYSIMG Q android x86 29 https://dl.google.com/android/repository/sys-img/android/x86-29_r08-linux.zip
SYSIMG Q android-tv x86 29 https://dl.google.com/android/repository/sys-img/android-tv/x86-29_r03.zip
SYSIMG Q google_apis x86_64 29 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-29_r12.zip
SYSIMG Q google_apis x86 29 https://dl.google.com/android/repository/sys-img/google_apis/x86-29_r12.zip
SYSIMG Q google_apis_playstore x86_64 29 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-29_r08-linux.zip
SYSIMG Q google_apis_playstore x86 29 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-29_r08-linux.zip
SYSIMG R android x86_64 30 https://dl.google.com/android/repository/sys-img/android/x86_64-30_r10.zip
SYSIMG R android-tv x86 30 https://dl.google.com/android/repository/sys-img/android-tv/x86-30_r03.zip
SYSIMG R google_apis x86_64 30 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-30_r11.zip
SYSIMG R google_apis x86 30 https://dl.google.com/android/repository/sys-img/google_apis/x86-30_r10.zip
SYSIMG R google_apis_playstore x86_64 30 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-30_r10-linux.zip
SYSIMG R google_apis_playstore x86 30 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86-30_r09-linux.zip
SYSIMG S android x86_64 31 https://dl.google.com/android/repository/sys-img/android/x86_64-31_r03.zip
SYSIMG S android-tv x86 31 https://dl.google.com/android/repository/sys-img/android-tv/x86-31_r03.zip
SYSIMG S google_apis x86_64 31 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-31_r09.zip
SYSIMG S google_apis_playstore x86_64 31 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-31_r09.zip
SYSIMG S google_apis x86_64 32 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-32_r03.zip
SYSIMG Tiramisu google_apis x86_64 32 https://dl.google.com/android/repository/sys-img/google_apis/x86_64-Tiramisu_r01.zip
SYSIMG S google_apis_playstore x86_64 32 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-32_r03-linux.zip
SYSIMG Tiramisu google_apis_playstore x86_64 32 https://dl.google.com/android/repository/sys-img/google_apis_playstore/x86_64-Tiramisu_r01.zip
EMU canary 31.3.4 macosx https://dl.google.com/android/repository/emulator-darwin_x64-8220659.zip
EMU canary 31.3.4 linux https://dl.google.com/android/repository/emulator-linux_x64-8220659.zip
EMU canary 31.3.4 windows https://dl.google.com/android/repository/emulator-windows_x64-8220659.zip
EMU stable 31.2.8 linux https://dl.google.com/android/repository/emulator-linux_x64-8143646.zip
EMU stable 31.2.8 windows https://dl.google.com/android/repository/emulator-windows_x64-8143646.zip
EMU stable 31.2.8 macosx https://dl.google.com/android/repository/emulator-darwin_x64-8143646.zip

EMU開頭是模擬器,其他是系統(tǒng)鏡像,我們選擇其中一個版本下載,同時下載linux版本模擬器。

//下載系統(tǒng)鏡像 SYSIMG S android x86_64 31 
wget https://dl.google.com/android/repository/sys-img/android/x86_64-31_r03.zip
//下載模擬器 EMU stable 31.2.8 linux
wget  https://dl.google.com/android/repository/emulator-linux_x64-8143646.zip

基于系統(tǒng)鏡像和模擬器創(chuàng)建dockerfile,dockerfile用于創(chuàng)建android 模擬器 的 docker image

//emu-docker create <emulator-zip> <system-image-zip>  [--dest docker-src-dir (getcwd()/src by default)]
emu-docker create  模擬器.zip 系統(tǒng)鏡像.zip --dest src
//--dest 指定生成dockerfile的存放路徑,默認(rèn)就是 pwd/src. 所以--dest src可以不加

官方說emu-docker create沒有生成可用的鏡像,需要 docker build 生成。 但實(shí)際生成了。也就是不用 src 目錄下docker build . 鏡像也存在了。
當(dāng)然也可以跟官方的操作執(zhí)行docker build . 再創(chuàng)建一個鏡像。

This places all the right elements to run a docker image, but does not build, run or publish yet. A Linux emulator zip file must be used.
cd src
docker build  .  
主要生成的docker鏡像有2個
#android系統(tǒng)docker鏡像
us-docker.pkg.dev/android-emulator-268719/images/sys-31-aosp-x64

上面android 系統(tǒng)鏡像的docker鏡像,基于模板 Dockerfile.system_image 生成.
Dockerfile.system_image主要步驟
拷貝android系統(tǒng)鏡像,解壓
基于 nvidia/opengl:1.2-glvnd-runtime-ubuntu20.04 創(chuàng)建鏡像
拷貝解壓的系統(tǒng)鏡像到容器 /android/sdk/system-images/android/ 目錄
拷貝 adb
chmod +x adb

#模擬器docker鏡像
us-docker.pkg.dev/android-emulator-268719/images/31-aosp-x64-no-metrics 

模擬器docker鏡像 基于模板 Dockerfile.emulator 生成
Dockerfile.emulator主要步驟
基于 上面的android系統(tǒng)docker鏡像
安裝相關(guān)依賴
拷貝 launch-emulator.sh 腳本(容器啟動用) 到 容器 /android/sdk/目錄
設(shè)置容器啟動命令:啟動執(zhí)行 launch-emulator.sh

src目錄下生成的docekrfile 就是基于Dockerfile.emulator模板的,這也是為什么說(官方說emu-docker create沒有生成可用的鏡像,需要 docker build 生成。 但實(shí)際生成了).

運(yùn)行容器

docker run -d \
  -e ADBKEY="$(cat ~/.android/adbkey)" \
  --device /dev/kvm \
  --publish 8554:8554/tcp \
  --publish 5555:5555/tcp  \
us-docker.pkg.dev/android-emulator-268719/images/31-aosp-x64-no-metrics 

--device /dev/kvm 表示需要用到kvm設(shè)備用于硬件加速,所以宿主機(jī)要支持kvm,本地機(jī)器沒問題,但是放到阿里云k8s服務(wù)上會有問題,因?yàn)闆]有kvm。不過阿里云有個 彈性云手機(jī)服務(wù)
通過adb 連接設(shè)備

 adb connect localhost:5555

也可以安裝 scrcpy投屏


image.png

launch-emulator.sh

介紹下launch-emulator.sh
主要是安裝證書,運(yùn)行模擬器

LAUNCH_CMD=emulator/emulator
var_append LAUNCH_CMD -avd Pixel2
var_append LAUNCH_CMD -ports 5556,5557 -grpc 8554 -no-window
var_append LAUNCH_CMD -skip-adb-auth -no-snapshot-save -wipe-data -no-boot-anim
var_append LAUNCH_CMD -shell-serial file:/tmp/android-unknown/kernel.log
var_append LAUNCH_CMD -logcat "*:V"
var_append LAUNCH_CMD -logcat-output /tmp/android-unknown/logcat.log
var_append LAUNCH_CMD -logcat "*:V"
var_append LAUNCH_CMD -feature AllowSnapshotMigration
var_append LAUNCH_CMD -gpu swiftshader_indirect {{extra}}

上面是構(gòu)造運(yùn)行模擬器的命令 emulator/emulator ....
其中 -grpc 8554 是用于對客戶端開放 grpc服務(wù),被 android-emulator-webrtc 用到。
也是網(wǎng)頁端顯示和操縱模擬器的基礎(chǔ)。
模擬器 grpc說明 emulator grpc

web端操作

生成3個鏡像

./create_web_container.sh -h
emulator_nginx
emulator_envoy
//就是us-docker.pkg.dev/android-emulator-268719/images/31-aosp-x64-no-metrics 
emulator_emulator

web端操作主要是通過grpc和android-emulator-webrtc
ngnix用于web端代理.
Envoy 也是代理,istio中的sidecar就是用的Envoy。這里用于proxy grpc給 android-emulator-webrtc 組件。

運(yùn)行

docker-compose -f js/docker/docker-compose.yaml up

Docker-compose 文件對emulator_nginx,emulator_envoy,emulator_emulator 3個服務(wù)作了編排。
啟動3個容器后就可以通過瀏覽器訪問模擬器了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容