Android 模拟器在 Gitlab 上失败 CI

Android emulator fails on Gitlab CI

我正在尝试 运行 android 在远程 linux 机器上的 Gitlab CI 上进行仪器测试,一切正常,直到它 运行s gradle 测试任务,它在没有任何进一步信息的情况下失败了。

我还应该提一下,十分之一的成功率。

你能发现问题吗?

这是我的 gitlab CI 文件:


variables:
  ANDROID_COMPILE_SDK: "30"
  ANDROID_BUILD_TOOLS: "30.0.3"
  ANDROID_SDK_TOOLS:   "6858069"
  ANDROID_APK_FOLDER:  "app/build/outputs/apk"
  EMULATOR_VERSION: "24"
  ENVIRONMENT: Staging

before_script:
  - export ANDROID_HOME=$PWD/android-sdk
  - export ANDROID_SDK_ROOT=${ANDROID_HOME}
  - export ANDROID_TOOLS_PATH=${ANDROID_HOME}/platform-tools
  - export ANDROID_SDK_MANAGER=${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager
  - export ANDROID_AVD_MANAGER=${ANDROID_HOME}/cmdline-tools/latest/bin/avdmanager
  - export ANDROID_EMULATOR_HOME=${ANDROID_HOME}/emulator
  - export ANDROID_EMULATOR_PATH=${ANDROID_HOME}/avd
  - export PATH="$PATH:${ANDROID_TOOLS_PATH}"
  - export ADB_INSTALL_TIMEOUT=10

  # Update system
  - apt-get --quiet update --yes
  - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 tree libx11-dev libpulse0 libgl1 libnss3 libxcomposite-dev libxcursor1 libasound2

  # Download Android SDK
  - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
  - mkdir ${ANDROID_HOME}
  - unzip -d ${ANDROID_HOME}/cmdline-tools android-sdk.zip
  - echo y | rm android-sdk.zip
  - mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest

  # Install Android Build Tools
  - echo y | ${ANDROID_SDK_MANAGER} --sdk_root=${ANDROID_HOME} --licenses
  - echo y | ${ANDROID_SDK_MANAGER} --sdk_root=${ANDROID_HOME} --update > update.log
  - echo y | ${ANDROID_SDK_MANAGER} --sdk_root=${ANDROID_HOME} "platforms;android-${ANDROID_COMPILE_SDK}" "build-tools;${ANDROID_BUILD_TOOLS}" "extras;google;m2repository" "extras;android;m2repository" > installPlatform.log

  # Create untracked files
  - echo -e "android.useAndroidX=true\nandroid.enableJetifier=true" > gradle.properties
  - echo ${RELEASE_KEYSTORE} | base64 -d > app/upload.jks

stages:
  - setup
  - e2e_test

setup:
  stage: setup
  script:
    - chmod +x ./gradlew
    - ./gradlew clean

############################################## TESTS ###############################################

e2e_test:
  stage: e2e_test
  only:
    - develop
    - tags
  script:
    - wget --quiet --output-document=android-wait-for-emulator.sh https://raw.githubusercontent.com/travis-ci/travis-cookbooks/0f497eb71291b52a703143c5cd63a217c8766dc9/community-cookbooks/android-sdk/files/default/android-wait-for-emulator
    - chmod +x android-wait-for-emulator.sh
    - echo y | ${ANDROID_SDK_MANAGER} --update > update.log
    - echo y | ${ANDROID_SDK_MANAGER} "platform-tools" "emulator" "system-images;android-${EMULATOR_VERSION};default;armeabi-v7a" > installEmulator.log
    - echo no | ${ANDROID_AVD_MANAGER} --verbose create avd -n test --force -k "system-images;android-${EMULATOR_VERSION};default;armeabi-v7a"
    - ${ANDROID_EMULATOR_HOME}/emulator -avd test -no-snapshot-save -no-audio -no-window -debug -verbose &
    - ./android-wait-for-emulator.sh
    - adb shell input keyevent 82
    - ./gradlew connected${ENVIRONMENT^}DebugAndroidTest --stacktrace --continue || true
    - adb devices | grep emulator | cut -f1 | while read line; do adb -s $line emu kill; done

这是我得到的错误:

> Task :app:connectedStagingDebugAndroidTest
Unable to install /builds/onl-dev-team/retail_checkout_app/app/build/outputs/apk/staging/debug/app-staging-2.2.1.apk
com.android.ddmlib.InstallException
    at com.android.ddmlib.internal.DeviceImpl.installRemotePackage(DeviceImpl.java:1316)
    at com.android.ddmlib.internal.DeviceImpl.installPackage(DeviceImpl.java:1136)
com.android.build.gradle.internal.testing.ConnectedDevice > runTests[test(AVD) - 7.0] FAILED 
    com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException
        at com.android.build.gradle.internal.testing.ConnectedDevice.installPackage(ConnectedDevice.java:133)
    at com.android.ddmlib.internal.DeviceImpl.installPackage(DeviceImpl.java:1112)
    at com.android.ddmlib.internal.DeviceImpl.installPackage(DeviceImpl.java:1101)
    at com.android.build.gradle.internal.testing.ConnectedDevice.installPackage(ConnectedDevice.java:127)
    at com.android.build.gradle.internal.testing.SimpleTestRunnable.run(SimpleTestRunnable.java:135)
    at com.android.build.gradle.internal.tasks.Workers$ProfileAwareExecutorServiceAdapter$submit$submission.run(Workers.kt:165)
    at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
    at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:691)
    at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:470)
    at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:727)
    at com.android.ddmlib.internal.DeviceImpl.installRemotePackage(DeviceImpl.java:1307)
    ... 12 more
[no message defined]

如本 post https://githubmemory.com/repo/mingchen/docker-android-build-box/issues/58 中所述, 在启动时,android 系统会经历很多过程,并且在尝试安装 apk 时可能很忙。这将导致例如 ShellCommandUnresponsiveException.

为了解决这个问题,我只是按照建议在 adb shell input keyevent 82

行后添加了一个 sleep 180