为什么Jenkins Android Emulator Plugin会在每次构建中重新创建我的仿真器快照?

时间:2012-11-14 15:07:53

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

我使用Jenkins构建我的一个项目。 Android Emulator插件使用以下配置自动启动模拟器:

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>

2 个答案:

答案 0 :(得分:8)

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

由于命令在没有列出可用快照的情况下崩溃,因此Android Emulator插件认为没有现有快照,这会导致在每次构建中创建新快照。

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

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

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

答案 1 :(得分:2)

除了Christopher Orr's answer之外,还有另一个可能的原因。在我的环境中,emulator -snapshot-list将我的快照大小列为“1.0G”。截至2014-01-14,与Android Emulator插件中的快照匹配的模式与整数兆字节值相匹配。

我提交了pull request来解决这个问题。