android - 为什么 Jenkins Android 模拟器插件会在每个构建中重新创建我的模拟器快照?

标签 android android-emulator jenkins hudson android-emulator-plugin

我使用 Jenkins 来构建我的一个项目。 Android Emulator Plugin 会自动启动具有以下配置的模拟器:

emulator configuration

模拟器插件的配置:

emulator plugin configuration .

每次作业运行时,我都会得到以下输出:

Erasing existing emulator data... $
/ci/home/tools/android-sdk//tools/emulator -no-boot-anim -ports
64470,64471 -prop persist.sys.language=de -prop persist.sys.country=DE
-avd hudson_de-DE_240_480x720_Google_Inc._Google_APIs_8 -no-snapshot-load -no-snapshot-save -wipe-data

.
.

shell input keyevent 4 [android] Giving the system some time to settle
before creating initial snapshot... $

.
.

localhost:64471 shell log -p v -t Jenkins "Creating snapshot..."
[android] Creating snapshot... $

下面的完整日志。

插件似乎每次都在创建一个新的模拟器,并且没有使用快照。 这需要 2 到 4 分钟,具体取决于模拟器配置。

插件在作业文件夹内的 .android/avd 目录中创建 .avd 和 .ini 文件。运行过程后avds不会被删除。

如果我禁用使用快照配置,模拟器需要不到一分钟的时间来启动。

这是模拟器插件的问题,还是因为我的配置无法创建快照?

我希望使用快照能大大加快我的构建过程。


完整日志:

$ /ci/home/tools/android-sdk//tools/android list target [android]
Using Android SDK: /ci/home/tools/android-sdk/ [android] Adding 200M
SD card to AVD 'hudson_de-DE_240_480x720_Google_Inc._Google_APIs_8'...
[android] Setting hardware properties:  hw.ramSize: 512
$ /ci/home/tools/android-sdk//platform-tools/adb start-server
$ /ci/home/tools/android-sdk//tools/emulator -snapshot-list -no-window -avd hudson_de-DE_240_480x720_Google_Inc._Google_APIs_8
[android] Starting Android emulator and creating initial snapshot
[android] Erasing existing emulator data...
$ /ci/home/tools/android-sdk//tools/emulator -no-boot-anim -ports 64470,64471 -prop persist.sys.language=de -prop persist.sys.country=DE -avd hudson_de-DE_240_480x720_Google_Inc._Google_APIs_8 -no-snapshot-load -no-snapshot-save -wipe-data
* daemon not running. starting it now on port 64472 *
* daemon started successfully *
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
[android] Waiting for emulator to finish booting...
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 
shell getprop dev.bootcomplete error: device offline
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell getprop dev.bootcomplete
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell getprop dev.bootcomplete
$ /ci/home/tools/android-sdk//platform-tools/adb disconnect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell getprop dev.bootcomplete
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell getprop dev.bootcomplete
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell getprop dev.bootcomplete
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 logcat -v time
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
[android] Attempting to unlock emulator screen
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell input keyevent 82
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell input keyevent 4
[android] Giving the system some time to settle before creating initial snapshot...
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 logcat -c
$ /ci/home/tools/android-sdk//platform-tools/adb -s localhost:64471 shell log -p v -t Jenkins "Creating snapshot..."
[android] Creating snapshot...
$ /ci/home/tools/android-sdk//platform-tools/adb connect localhost:64471
[android] Emulator is ready for use (took 158 seconds)

示例作业的构建文件:

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <scm class="hudson.plugins.git.GitSCM">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <name></name>
        <refspec></refspec>
        <url>git@project...</url>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>master</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <disableSubmodules>false</disableSubmodules>
    <recursiveSubmodules>false</recursiveSubmodules>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <authorOrCommitter>false</authorOrCommitter>
    <clean>false</clean>
    <wipeOutWorkspace>false</wipeOutWorkspace>
    <pruneBranches>false</pruneBranches>
    <remotePoll>false</remotePoll>
    <ignoreNotifyCommit>false</ignoreNotifyCommit>
    <useShallowClone>false</useShallowClone>
    <buildChooser class="hudson.plugins.git.util.DefaultBuildChooser"/>
    <gitTool>default</gitTool>
    <submoduleCfg class="list"/>
    <relativeTargetDir></relativeTargetDir>
    <reference></reference>
    <excludedRegions></excludedRegions>
    <excludedUsers></excludedUsers>
    <gitConfigName></gitConfigName>
    <gitConfigEmail></gitConfigEmail>
    <skipTag>false</skipTag>
    <includedRegions></includedRegions>
    <scmName></scmName>
  </scm>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>true</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>true</blockBuildWhenUpstreamBuilding>
  <triggers class="vector">
    <hudson.triggers.SCMTrigger>
      <spec>*/5 * * * *</spec>
    </hudson.triggers.SCMTrigger>
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Ant>
      <targets>clean debug install</targets>
      <antName>(Default)</antName>
    </hudson.tasks.Ant>
    <hudson.tasks.Ant>
      <targets></targets>
      <antName>(Default)</antName>
      <buildFile>checkstyle-ant.xml</buildFile>
    </hudson.tasks.Ant>
    <hudson.tasks.Shell>
      <command>os_opts=&quot;-Djava.awt.headless=true&quot; lint --xml lint-results.xml .</command>
    </hudson.tasks.Shell>
    <hudson.plugins.android__emulator.monkey.MonkeyBuilder>
      <packageId>de....</packageId>
      <eventCount>1000</eventCount>
      <throttleMs>10</throttleMs>
      <seed>timestamp</seed>
    </hudson.plugins.android__emulator.monkey.MonkeyBuilder>
    <hudson.tasks.Shell>
        ... distribution script
    </hudson.tasks.Shell>
  </builders>
  <publishers>
    <org.jenkinsci.plugins.android__lint.LintPublisher>
      <healthy></healthy>
      <thresholdLimit>low</thresholdLimit>
      <pluginName>[android-lint] </pluginName>
      <defaultEncoding></defaultEncoding>
      <canRunOnFailed>false</canRunOnFailed>
      <useStableBuildAsReference>false</useStableBuildAsReference>
      <useDeltaValues>false</useDeltaValues>
      <thresholds>
        <unstableTotalAll></unstableTotalAll>
        <unstableTotalHigh></unstableTotalHigh>
        <unstableTotalNormal></unstableTotalNormal>
        <unstableTotalLow></unstableTotalLow>
        <unstableNewAll></unstableNewAll>
        <unstableNewHigh></unstableNewHigh>
        <unstableNewNormal></unstableNewNormal>
        <unstableNewLow></unstableNewLow>
        <failedTotalAll></failedTotalAll>
        <failedTotalHigh></failedTotalHigh>
        <failedTotalNormal></failedTotalNormal>
        <failedTotalLow></failedTotalLow>
        <failedNewAll></failedNewAll>
        <failedNewHigh></failedNewHigh>
        <failedNewNormal></failedNewNormal>
        <failedNewLow></failedNewLow>
      </thresholds>
      <shouldDetectModules>false</shouldDetectModules>
      <dontComputeNew>false</dontComputeNew>
      <doNotResolveRelativePaths>false</doNotResolveRelativePaths>
      <pattern></pattern>
    </org.jenkinsci.plugins.android__lint.LintPublisher>
    <hudson.plugins.checkstyle.CheckStylePublisher>
      <healthy></healthy>
      <unHealthy></unHealthy>
      <thresholdLimit>low</thresholdLimit>
      <pluginName>[CHECKSTYLE] </pluginName>
      <defaultEncoding></defaultEncoding>
      <canRunOnFailed>false</canRunOnFailed>
      <useStableBuildAsReference>false</useStableBuildAsReference>
      <useDeltaValues>false</useDeltaValues>
      <thresholds>
        <unstableTotalAll></unstableTotalAll>
        <unstableTotalHigh></unstableTotalHigh>
        <unstableTotalNormal></unstableTotalNormal>
        <unstableTotalLow></unstableTotalLow>
        <failedTotalAll></failedTotalAll>
        <failedTotalHigh></failedTotalHigh>
        <failedTotalNormal></failedTotalNormal>
        <failedTotalLow></failedTotalLow>
      </thresholds>
      <shouldDetectModules>false</shouldDetectModules>
      <dontComputeNew>true</dontComputeNew>
      <doNotResolveRelativePaths>false</doNotResolveRelativePaths>
      <pattern></pattern>
    </hudson.plugins.checkstyle.CheckStylePublisher>
    <hudson.plugins.warnings.WarningsPublisher>
      <healthy></healthy>
      <unHealthy></unHealthy>
      <thresholdLimit>low</thresholdLimit>
      <pluginName>[WARNINGS] </pluginName>
      <defaultEncoding></defaultEncoding>
      <canRunOnFailed>false</canRunOnFailed>
      <useStableBuildAsReference>false</useStableBuildAsReference>
      <useDeltaValues>false</useDeltaValues>
      <thresholds>
        <unstableTotalAll></unstableTotalAll>
        <unstableTotalHigh></unstableTotalHigh>
        <unstableTotalNormal></unstableTotalNormal>
        <unstableTotalLow></unstableTotalLow>
        <failedTotalAll></failedTotalAll>
        <failedTotalHigh></failedTotalHigh>
        <failedTotalNormal></failedTotalNormal>
        <failedTotalLow></failedTotalLow>
      </thresholds>
      <shouldDetectModules>false</shouldDetectModules>
      <dontComputeNew>true</dontComputeNew>
      <doNotResolveRelativePaths>true</doNotResolveRelativePaths>
      <parserConfigurations/>
      <consoleParsers>
        <hudson.plugins.warnings.ConsoleParser>
          <parserName>Java Compiler (Eclipse)</parserName>
        </hudson.plugins.warnings.ConsoleParser>
      </consoleParsers>
    </hudson.plugins.warnings.WarningsPublisher>
    <hudson.plugins.analysis.collector.AnalysisPublisher>
      <healthy></healthy>
      <unHealthy></unHealthy>
      <thresholdLimit>low</thresholdLimit>
      <pluginName>[ANALYSIS-COLLECTOR] </pluginName>
      <defaultEncoding></defaultEncoding>
      <canRunOnFailed>false</canRunOnFailed>
      <useStableBuildAsReference>false</useStableBuildAsReference>
      <useDeltaValues>false</useDeltaValues>
      <thresholds>
        <unstableTotalAll></unstableTotalAll>
        <unstableTotalHigh></unstableTotalHigh>
        <unstableTotalNormal></unstableTotalNormal>
        <unstableTotalLow></unstableTotalLow>
        <failedTotalAll></failedTotalAll>
        <failedTotalHigh></failedTotalHigh>
        <failedTotalNormal></failedTotalNormal>
        <failedTotalLow></failedTotalLow>
      </thresholds>
      <shouldDetectModules>false</shouldDetectModules>
      <dontComputeNew>true</dontComputeNew>
      <doNotResolveRelativePaths>true</doNotResolveRelativePaths>
      <isCheckStyleDeactivated>false</isCheckStyleDeactivated>
      <isDryDeactivated>true</isDryDeactivated>
      <isFindBugsDeactivated>true</isFindBugsDeactivated>
      <isPmdDeactivated>true</isPmdDeactivated>
      <isOpenTasksDeactivated>true</isOpenTasksDeactivated>
      <isWarningsDeactivated>false</isWarningsDeactivated>
    </hudson.plugins.analysis.collector.AnalysisPublisher>
    <hudson.plugins.android__emulator.monkey.MonkeyRecorder>
      <failureOutcome>FAILURE</failureOutcome>
    </hudson.plugins.android__emulator.monkey.MonkeyRecorder>
    <hudson.plugins.cigame.GamePublisher/>
    <hudson.tasks.Mailer>
      <recipients></recipients>
      <dontNotifyEveryUnstableBuild>false</dontNotifyEveryUnstableBuild>
      <sendToIndividuals>true</sendToIndividuals>
    </hudson.tasks.Mailer>
  </publishers>
  <buildWrappers>
    <hudson.plugins.locksandlatches.LockWrapper>
      <locks>
        <hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig>
          <name>AndroidEmulator</name>
        </hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig>
      </locks>
    </hudson.plugins.locksandlatches.LockWrapper>
    <hudson.plugins.android__emulator.AndroidEmulator>
      <osVersion>Google Inc.:Google APIs:8</osVersion>
      <screenDensity>240</screenDensity>
      <screenResolution>480x720</screenResolution>
      <deviceLocale>de_DE</deviceLocale>
      <sdCardSize>200M</sdCardSize>
      <hardwareProperties>
        <hudson.plugins.android__emulator.AndroidEmulator_-HardwareProperty>
          <key>hw.ramSize</key>
          <value>512</value>
        </hudson.plugins.android__emulator.AndroidEmulator_-HardwareProperty>
      </hardwareProperties>
      <wipeData>false</wipeData>
      <showWindow>true</showWindow>
      <useSnapshots>true</useSnapshots>
      <deleteAfterBuild>false</deleteAfterBuild>
      <startupDelay>0</startupDelay>
      <commandLineOptions></commandLineOptions>
    </hudson.plugins.android__emulator.AndroidEmulator>
  </buildWrappers>
</project>

最佳答案

一个 bug was introduced在 SDK Tools r20 中,尝试列出可用快照(通过 emulator -snapshot-list 命令)会导致崩溃。

由于该命令在未列出可用快照的情况下崩溃,Android Emulator Plugin 认为没有现有快照,这会导致在每个构建中创建一个新快照。

我发现这些崩溃只发生在 certain versions 上。 emulator 应用程序,即可以避免崩溃。

幸运的是,Jenkins 插件允许您选择要运行的 emulator 二进制文件。

因此,您可以通过进入作业配置、在模拟器配置中按 Advanced… 并选择“emulator-arm”(或其他)来解决此问题二进制。

关于android - 为什么 Jenkins Android 模拟器插件会在每个构建中重新创建我的模拟器快照?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13381460/

相关文章:

android - CardView 海拔未显示在 Lollipop 和更高版本中

安卓工作室 : emulator won't install

jenkins - jenkins 环境变量中的三元运算符

android - Chromecast SDK (Android) - 有没有办法检查在转换设备上播放的媒体是否已经播放完毕?

android - 左/中/右对齐 LinearLayout - Android

android - Google Developers 不允许我使用 android.hardware.Camera 或 camera2

Android Studio - 模拟器 - eglSurfaceAttrib 未实现

Android 模拟器有时显示 "Storage space running out",使 APK 安装时 adb 挂起

Jenkins从节点离线: Authentication failed

jenkins - kubernetes slaves 无法注册到 jenkins master