在 docker 容器中运行 Android 模拟器
Posted
技术标签:
【中文标题】在 docker 容器中运行 Android 模拟器【英文标题】:Running Android emulator in docker container 【发布时间】:2021-10-02 22:57:45 【问题描述】:我们正在使用 wix/Detox 在 React Native 中构建一个应用程序来编写 e2e 测试。
我们使用 Docker 进行构建和运行测试。具体来说,我们正在使用社区 react-native-android Docker 映像。
我已将 fastlane 添加到映像中以构建/发布我们的应用程序,现在尝试添加一个模拟器,以便我们也可以运行测试。
这是我们的 Dockerfile:
# reactnativecommunity/react-native-android:4.0
FROM reactnativecommunity/react-native-android@sha256:c3ad9b8ed5caac0718b1c1b8f10469eb75b0ac77c86143c94f9616ee46b80b4b
RUN gem install fastlane -NV
RUN sdkmanager --install "system-images;android-31;google_apis;arm64-v8a"
RUN echo no | avdmanager create avd --name default -k "system-images;android-31;google_apis;arm64-v8a"
但是,当我运行容器并尝试启动模拟器时,我得到以下信息:
root@7b862aa149c8:/# emulator -no-audio -no-boot-anim -no-window -use-system-libs @default
emulator: Android emulator version 30.7.5.0 (build_id 7491168) (CL:N/A)
emulator: INFO: ignore sdcard for arm at api level >= 30
emulator: feeding guest with passive gps data, in headless mode
emulator: ERROR: AdbHostServer.cpp:102: Unable to connect to adb daemon on port: 5037
cannot add library /opt/android/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so: failed
added library /opt/android/emulator/lib64/vulkan/libvulkan.so
emulator: INFO: ignore sdcard for arm at api level >= 30
emulator: INFO: userspace-boot-properties.cpp:242: Sending adb public key [QAAAACG/f/Yfe1MON5LKVoRU+iuzZRCKQTvsqLWcWh8i5ii03oHLY7y7U+0uKSE5x84OrGS0g6G9HTU7Mazh18yhbmPAQociSCfrSRIWg3IAdduFDgYPnY2G3Lj11ZLQoyRt4+xXO7zVcUPtwERpgpYQXEN5KkkEZBUxxWvrejENPAffPp4DHFqJf63sAUPh9qo6cwfSMylnl7RTBicxZ+tuDwrxA1JgcvklAs38E9gzxjNDed+1VibNUjzCtRl4DnPPmIk1OqhvjU0xZV//YXDrdhb++jQOpcKAzkCvVks4RUjJ1okytnmDfh+YUH4thQYuqNdEBnGM4wz8cPQH0YjO1SsK2sOrD0VJaGjSDAwsjne2QCFy5ET+HOUcMNKCaC60MAcCgWXLm8MdoaVLgjoG0jbUEkr/BJ2hpN7/p+qi8qMSg3Vv2M/4kdHmIEzDpJTd8TFD1bbrRjdUIheDzE1b00SKhQzDJ39sQim31IqWGuRIJ4Cb39VaHCFK6ZwZPpG9KKLSV1ww5KCKVgSsJ5zaAvhagCjXXXVrtl40v72zYq/c0BtUG4LhLixtz/zuT1WFKq8HoGFkJBvw5fBVqcvOn6yN7xI3DAuzAlQcHPyRQdHm72+//KimCVHnkxlL3hpRMir06QhMk2DsKTntXjbYuhCCn0aetEUUpai6gl1NuCbv92QlDgEAAQA= @unknown]
emulator: INFO: GrpcServices.cpp:315: Started GRPC server at 127.0.0.1:8554, security: Local
WARNING. Using fallback path for the emulator registration directory.
emulator: INFO: EmulatorAdvertisement.cpp:93: Advertising in: /root/.android/avd/running/pid_9.ini
qemu-system-aarch64-headless: PCI bus not available for hda
saving arm snapshot.... !!!
saving done.... !!!
root@7b862aa149c8:/#
【问题讨论】:
您是否尝试添加此行的末尾?模拟器 -avd $AVD_NAME -no-audio -no-cache -no-snapshot -no-window & echo "等待设备准备好" ADB 等待设备 @Arunachalamk 这对你有用吗(添加-no-cache -no-snapshot
)或者你只是建议尝试一些事情?
【参考方案1】:
所以,
是否可以通过 Docker 运行 (Android) 模拟器? 可以。
我对 Fastlane|wix/Detox 了解不多,但我在一个 e2e/Appium 项目中做了这个
如果是这样,怎么做? 您需要支持虚拟化的硬件
在 Linux 中查看 CPU 是否支持 KVM 的 Intel VT/AMD-V 虚拟化
lscpu | grep 虚拟化
虚拟化:VT-x(如果支持“Intel VT-x”或“VT-x”功能)
或
虚拟化:完整(如果不支持“完整”)
On AWS, you need a bare metal instance (supported x86) like c5.metal
-
Android 模拟器容器脚本
https://github.com/google/android-emulator-container-scripts
按照这个 git,使用 google API(我的情况是 27-google-x86)创建一个图像并放入 docker repo,比如 AWS ECR。
而且,我也为 Appium 创建了一个图像(我相信使用 wix/detox 是可能的)
到 SDK
Dockerfile
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
# Installs i386 architecture required for running 32 bit Android tools
RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get dist-upgrade -y && \
apt-get install -y --no-install-recommends openjdk-8-jdk && \
apt-get install -y --no-install-recommends git wget unzip curl make && \
rm -rf /var/lib/apt/lists/* && \
apt-get autoremove -y && \
apt-get clean
ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/jre" \
PATH=$PATH:$JAVA_HOME/bin
# Installs Android SDK
ENV ANDROID_HOME=/android-sdk
ENV ANDROID_SDK_HOME $ANDROID_HOME
ARG ANDROID_SDK_VERSION=6514223
ARG ANDROID_BUILD_TOOLS_VERSION=27.0.0
ARG ANDROID_PLATFORM_VERSION="android-27"
RUN mkdir -p $ANDROID_SDK_HOME/cmdline-tools && \
wget -q https://dl.google.com/android/repository/commandlinetools-linux-$ANDROID_SDK_VERSION_latest.zip && \
unzip *tools*linux*.zip -d $ANDROID_SDK_HOME/cmdline-tools && \
rm *tools*linux*.zip
ENV PATH $PATH:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools
RUN mkdir -p ~/.android && \
touch ~/.android/repositories.cfg && \
echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager --licenses && \
echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "platform-tools" && \
echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "build-tools;$ANDROID_BUILD_TOOLS_VERSION" && \
echo y | $ANDROID_SDK_HOME/cmdline-tools/tools/bin/sdkmanager "platforms;$ANDROID_PLATFORM_VERSION"
# Installs Node
ARG NODE_VERSION=12.x
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION | bash
RUN apt-get install --yes nodejs
-
最后,我将所有内容都编排成了一个 Jenkinsfile
【讨论】:
好的,所以当你说“跟随这个 git,使用 google API(我的情况是 27-google-x86)创建一个图像并放入 docker repo,比如 AWS ECR”时——试过了,并收到错误:emu_docker.py", line 128, in create_docker_image_interactive sys_docker = SystemImageContainer(img, args.repo) AttributeError: 'Namespace' object has no attribute 'repo
.
我可以直接启动他们的 Docker 镜像(例如us-docker.pkg.dev/android-emulator-268719/images/30-google-x64-no-metrics:30.1.2
),但它是一个完整的黑匣子——所以它作为二进制“工作”,但没有回答我的问题 如何我自己来做这件事,所以我可以把它作为一个起点。例如他们的图像基于 Debian 9,无法找到更新的方法,因为找不到匹配的 Dockerfile
以查看他们为创建此所做的工作。
所以,唯一可以使用 ARM 架构的就是 system-images;android-25;google_apis;armeabi-v7a
但它完全不实用,因为启动模拟器需要 +30 分钟,而实际安装应用程序也需要花费 30 分钟.是的,使用 Intel x86_64 效果更好,例如system-images;android-31;google_apis;x86_64
但确实需要裸机【参考方案2】:
这最终奏效了,但需要裸机
# reactnativecommunity/react-native-android:4.0
FROM reactnativecommunity/react-native-android@sha256:c3ad9b8ed5caac0718b1c1b8f10469eb75b0ac77c86143c94f9616ee46b80b4b
ARG IMAGE="system-images;android-31;google_apis;x86_64"
RUN sdkmanager --install "$IMAGE"
RUN echo no | avdmanager create avd --name emulator_for_e2e_testing -k "$IMAGE"
ENTRYPOINT adb start-server && emulator -avd emulator_for_e2e_testing -no-audio -no-window -no-boot-anim
【讨论】:
嗯,希望在 Github 中将其用于 CI,但我想我最好完全摆脱 Docker 并咬紧牙关设置自托管运行器以上是关于在 docker 容器中运行 Android 模拟器的主要内容,如果未能解决你的问题,请参考以下文章