I use Jenkins to build one of my projects. The Android Emulator Plugin automatically starts an emulator with the following configuration:
Configuration of the Emulator Plugin:
.
Every time the job is running I get the following output:
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... $
Full log below.
It seems that the plugin is creating a new emulator every time and is not using snapshots. This takes something between 2 and 4 minutes depending on the emulator configuration.
The plugin creates .avd and .ini files in the .android/avd directory inside the job folder. The avds are not deleted after the run process.
If I disable the use snapshots config the emulator needs less then a minute to start.
Is this an issue with the emulator plugin or are snapshots not possible because of my configuration?
I hope that using snapshots will speed up my building process a lot.
Full log:
$ /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)
Buildfile for an example job:
<?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="-Djava.awt.headless=true" 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>
A bug was introduced in SDK Tools r20, whereby trying to list the available snapshots (via the
emulator -snapshot-list
command) would result in a crash.Since the command crashes without listing the available snapshots, the Android Emulator Plugin believes that there are no existing snapshots, which causes a new snapshot to be created in every build.
I discovered that these crashes only occur with certain versions of the
emulator
application, i.e. it is possible to avoid the crash.Thankfully, the Jenkins plugin lets you select the
emulator
binary to run.So you can work around this problem by going into your job configuration, pressing Advanced… in the emulator config and selecting the "
emulator-arm
" (or another) binary.In addition to Christopher Orr's answer, there is another possible cause. In my environment,
emulator -snapshot-list
listed the size of my snapshot as "1.0G". The pattern that matches snapshots in the Android Emulator Plugin as of 2014-01-14 matches whole number megabyte values.I submitted a pull request to address that cause.