【发布时间】:2021-04-26 08:17:20
【问题描述】:
最终更新 - 解决方案 - 连接到正确端口后安装失败,因为安装leaked file descriptors。按照here 中的建议更新环境变量可以解决问题
更新2 似乎环境变量会更改 gradle 命令的目标端口,但不会更改模拟器插件本身的等待循环。我决定手动启动模拟器
/var/lib/jenkins/android-sdk/emulator/emulator -avd testing24xlarge2 -wipe-data -no-window -no-audio -partition-size 4096 -ports 5558,5559&
EMULATOR_PID=$!
在这里我意识到,我没有指定 adb 超时,所以我决定使用插件之前使用的 tcp 端口并重试,但这一点帮助都没有。
/var/lib/jenkins/android-sdk/emulator/emulator -report-console tcp:5829,max=96000 -avd testing24xlarge2 -wipe-data -no-window -no-audio -partition-size 4096 -ports 5558,5559&
EMULATOR_PID=$!
。我能想到的一个可能但不太可能的原因是调试 apk 太大(我尝试的应用程序从 200 Mb 到 700 mb 不等)可能会导致此问题,但错误消息似乎并未表明这一点。尝试使用 adb 命令而不是 gradle 任务安装应用程序也没有帮助
android {
adbOptions {
timeOutInMs 6000000 // set timeout to 100 minutes
}
}
./gradlew assembleStagingDebug --no-daemon -Dkotlin.compiler.execution.strategy="in-process"
./gradlew assembleStagingDebugAndroidTest --no-daemon -Dkotlin.compiler.execution.strategy="in-process"
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 shell input keyevent 82
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 install -r -t myapp/build/outputs/apk/staging/debug/myapp-staging-debug.apk
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 install -r -t myapp/build/outputs/apk/androidTest/staging/debug/myapp-staging-debug-androidTest.apk
#/var/lib/jenkins/android-sdk/platform-tools/adb -e shell am instrument -w mypackage.testcases.tests/androidx.test.runner.AndroidJUnitRunner
在我尝试使用“可接受的 apk 大小”后,我会再次更新这篇文章
更新:我认为我已经正确识别了问题,但我仍然无法解决问题。
Ddmlib 会查找 5555,5586 之间的端口,当模拟器位于不同的端口时,应用程序安装自然会失败。
In official docs 建议我们可以利用环境变量让模拟器插件在我们想要的端口中搜索设备。但是与端口相关的环境变量(ANDROID_SERIAL, ANDROID_AVD_DEVICE 等)(我在我的主 Jenkins 配置中设置)都没有改变 adb -s 的目标。因此,使用ports 5558,5559 手动更改端口模拟器会失败,因为模拟器在端口 5558 中启动,但是
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5776 wait-for-device shell getprop dev.bootcomplete
在模拟器插件的随机分配端口中运行,当模拟器在我选择的端口中启动时卡住了。
_______________________________________________________________________________
在解决了数十个不同的问题以在模拟器中打开和运行 UI 测试后,我希望我被困在最后一个问题上,我尝试了所有我能想到的方法,但没有成功。
环境:我在 Min SDK = 24 的应用中使用 API 级别为 24 的模拟器以避免 INCOMPATIBLE_DEVICE_ERROR。 Jenkins 在 Ubuntu 20.04 中运行,但我认为这并不重要。我的目标 sdk 和编译 sdk 是 28(我也会尝试降级它们,但由于我已经解决了 INCOMPATIBLE 错误,我怀疑这会解决问题)。 Adb timeout 是 96000 秒,startup delay 是 20 秒。
正如下面的脚本将演示的那样,我很确定,我可以通过 adb 命令找到连接的模拟器,但是在安装和运行测试时,我尝试了两种不同的解决方案,但我都卡住了。
第一次解决方案尝试
while [ "`/var/lib/jenkins/android-sdk/platform-tools/adb shell getprop service.bootanim.exit | tr -d '\r' `" != "1" ] ; do sleep 1; done
/var/lib/jenkins/android-sdk/platform-tools/adb devices -l
/var/lib/jenkins/android-sdk/platform-tools/adb shell input keyevent 82
./gradlew myapp:connectedStagingDebugAndroidTest --no-daemon -Dkotlin.compiler.execution.strategy="in-process"
它正确地等待设备启动(android 模拟器插件也在此之前检查 sys.boot_completed)并列出连接的设备 /passes the input key event 82
这会导致以下错误
om.android.build.gradle.internal.testing.ConnectedDevice > runTests[testing24xlarge2(AVD) - 7.0] [31mFAILED [0m
com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException
at com.android.build.gradle.internal.testing.ConnectedDevice.installPackage(ConnectedDevice.java:132)
[no message defined]
java.util.concurrent.ExecutionException: java.lang.RuntimeException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1006)
at com.android.ide.common.workers.ExecutorServiceAdapter.await(ExecutorServiceAdapter.kt:102)
at com.android.build.gradle.internal.testing.BaseTestRunner.runTests(BaseTestRunner.java:201)
at com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask.lambda$doTaskAction$2(DeviceProviderInstrumentTestTask.java:201)
at com.android.builder.testing.api.DeviceProvider.use(DeviceProvider.java:53)
at com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask.doTaskAction(DeviceProviderInstrumentTestTask.java:191)
at
Caused by: java.lang.RuntimeException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException
at com.android.build.gradle.internal.testing.SimpleTestRunnable.run(SimpleTestRunnable.java:231)
Caused by: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException
at com.android.build.gradle.internal.testing.ConnectedDevice.installPackage(ConnectedDevice.java:132)
at com.android.build.gradle.internal.testing.SimpleTestRunnable.run(SimpleTestRunnable.java:134)
... 116 more
Caused by: com.android.ddmlib.InstallException
at com.android.ddmlib.Device.installRemotePackage(Device.java:1174)
at com.android.ddmlib.Device.installPackage(Device.java:998)
at com.android.ddmlib.Device.installPackage(Device.java:974)
at com.android.ddmlib.Device.installPackage(Device.java:963)
at com.android.build.gradle.internal.testing.ConnectedDevice.installPackage(ConnectedDevice.java:126)
... 117 more
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:553)
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:378)
at com.android.ddmlib.Device.executeShellCommand(Device.java:675)
at com.android.ddmlib.Device.installRemotePackage(Device.java:1165)
... 121 more
(我试图在不限制重要信息的情况下尽可能多地削减异常链)
这里可以看到模拟器已附加
+ /var/lib/jenkins/android-sdk/platform-tools/adb devices -l
List of devices attached
emulator-5802 device product:sdk_google_phone_armv7 model:sdk_google_phone_armv7 device:generic transport_id:1
第二次解决方案尝试建议here here 也不起作用
./gradlew clean
./gradlew assembleDebug
./gradlew assembleDebugAndroidTest
/var/lib/jenkins/android-sdk/platform-tools/adb install app/build/outputs/apk/app-debug.apk
/var/lib/jenkins/android-sdk/platform-tools/adb install app/build/outputs/apk/app-debug-androidTest-unaligned.apk
/var/lib/jenkins/android-sdk/platform-tools/adbshell am instrument -w com.google.samples.apps.topeka.test/android.support.test.runner.AndroidJUnitRunner
这里的问题是之后
/var/lib/jenkins/android-sdk/platform-tools/adb shell input keyevent 82
/var/lib/jenkins/android-sdk/platform-tools/adb install -r -t -g myapp/build/outputs/apk/staging/debug/myapp-staging-debug.apk //I have also tried adb -e to target the emulator as it is the only running device
控制台输出只是在安装命令处冻结(带有标志和不带标志 -r -t -g),并且您可能猜到下一个命令不会被执行。等了很长时间后,我收到以下错误,说 adb 可能无法工作,因为端口模拟器在。
adb: failed to install myapp/build/outputs/apk/staging/debug/myapp-staging-debug.apk: Performing Streamed Install
Build step 'Execute shell' marked build as failure
[android] Stopping Android emulator
emulator: WARNING: encryption is off
emulator: feeding guest with passive gps data, in headless mode
emulator: WARNING: Requested adb port (5775) is outside the recommended range [5555,5586]. ADB may not function properly for the emulator. See -help-port for details.
saving arm snapshot.... !!!
这是否因为端口错误而失败?如何在 Emulator Plugin 中指定我想要的端口号?它只让我
分配唯一的 TCP 端口以避免冲突。如果我在模拟器选项中指定它,它仍然会尝试使用它分配的随机端口执行 adb 命令,所以这不起作用。接下来我尝试复制我在控制台中看到的脚本来自己启动模拟器,但它似乎也不起作用(当我手动添加命令时模拟器没有启动
/var/lib/jenkins/android-sdk/platform-tools/adb start-server
/var/lib/jenkins/android-sdk/emulator/emulator -report-console tcp:5845,max=96000 -avd testing24xlarge2 -wipe-data -no-window -partition-size 4096 -ports 5558,5559
while [ "`/var/lib/jenkins/android-sdk/platform-tools/adb shell getprop service.bootanim.exit | tr -d '\r' `" != "1" ] ; do sleep 1; done //Doesn't pass here
我完全被困在这里并且可能失去了我的大部分头发,第一次解决方案尝试的修复或第二次解决方案尝试都是可以接受的。
【问题讨论】:
标签: android jenkins android-emulator adb avd