I have an Android Studio project for an Android SDK 35, with an Emulator Android version 15. My project builds on the Android Studio IDE and also the Emulator from the IDE can run the Android Instrumented Tests.
I've build a Docker Image using this Dockerfile:
# Use the base image with Android SDK
FROM mobiledevops/android-sdk-image:latest
WORKDIR /app
USER root
# Set environment variables for Android SDK and AVD paths
ENV ANDROID_HOME=/sdk
ENV ANDROID_SDK_ROOT=/sdk
ENV ANDROID_AVD_HOME=/root/.android/avd
ENV PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$PATH"
# Download and install Android cmdline-tools
RUN mkdir -p $ANDROID_HOME/cmdline-tools && \
curl -o /cmdline-tools.zip .zip && \
unzip /cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools && \
mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest && \
rm /cmdline-tools.zip
# Install required SDK components
RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses && \
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install \
"cmdline-tools;latest" \
"platform-tools" \
"emulator" \
"platforms;android-35" \
"system-images;android-35;google_apis;x86_64"
# Create the AVD with x86_64 system image for API Level 35
RUN echo "no" | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n testAVD -k "system-images;android-35;google_apis;x86_64" -d "pixel" --force
# Copy the project files into the container
COPY . .
# Add local.properties for SDK location
RUN echo "sdk.dir=$ANDROID_HOME" > local.properties
# Make the Gradle wrapper executable
RUN chmod +x ./gradlew
# Build the APK
RUN ./gradlew clean assembleRelease
# Default command for debugging (optional)
CMD ["/bin/bash"]
Docker image is created, however, when I start the container, after building the project and starting the emulator, when starting the emulator I get this output:
root@d53760c05e4f:/app# $ANDROID_HOME/emulator/emulator -avd testAVD -no-audio -no-window -accel off &
adb wait-for-device
[1] 18
* daemon not running; starting now at tcp:5037
INFO | Android emulator version 35.3.11.0 (build_id 12836668) (CL:N/A)
INFO | Graphics backend: gfxstream
INFO | Found systemPath /sdk/system-images/android-35/google_apis/x86_64/
INFO | Increasing RAM size to 2048MB
INFO | Checking system compatibility:
INFO | Checking: hasSufficientDiskSpace
INFO | Ok: Disk space requirements to run avd: `testAVD` are met.
INFO | Checking: hasSufficientHwGpu
INFO | Ok: Hardware GPU requirements to run avd: `testAVD` are passed.
INFO | Checking: hasSufficientSystem
INFO | Ok: System requirements to run avd: `testAVD` are met.
WARNING | File System is not ext4, disable QuickbootFileBacked feature
WARNING | x86_64 emulation may not work without hardware acceleration!
INFO | Storing crashdata in: /tmp/android-unknown/emu-crash-35.3.11.db, detection is enabled for process: 18
WARNING | Your GPU drivers may have a bug. Switching to software rendering.
library_mode swangle_indirect gpu mode swangle_indirect
INFO | Initializing hardware OpenGLES emulation support
I0207 10:48:05.764774 18 opengles.cpp:285] android_startOpenglesRenderer: gpu info
I0207 10:48:05.764903 18 opengles.cpp:286]
INFO | Not raising nofile soft limit from 1048576.
INFO | HealthMonitor disabled.
INFO | initIcdPaths: ICD set to 'swiftshader', using Swiftshader ICD
INFO | Setting ICD filenames for the loader = /sdk/emulator/qemu/linux-x86_64/lib64/vulkan/vk_swiftshader_icd.json:/sdk/emulator/lib64/vulkan/vk_swiftshader_icd.json
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] (posix,linux): call dlopen on [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] failed (posix). dlerror: []
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] (posix,linux): call dlopen on [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] failed (posix). dlerror: []
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so] (posix,linux): call dlopen on [/sdk/emulator/lib64/vulkan/libvulkan.so]
INFO | Added library: /sdk/emulator/lib64/vulkan/libvulkan.so
INFO | Selecting Vulkan device: SwiftShader Device (Subzero), Version: 1.3.0
INFO | Supports id properties, got a vulkan device UUID
INFO | SharedLibrary::open for [libGLESv2.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [libGLESv2.so] (posix): begin
INFO | SharedLibrary::open for [libGLESv2.so] (posix,linux): call dlopen on [libGLESv2.so]
INFO | SharedLibrary::open for [libEGL.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [libEGL.so] (posix): begin
INFO | SharedLibrary::open for [libEGL.so] (posix,linux): call dlopen on [libEGL.so]
INFO | SharedLibrary::open for [libX11]
INFO | SharedLibrary::open for [libX11]: not found in map, open for the first time
INFO | SharedLibrary::open for [libX11] (posix): begin
INFO | SharedLibrary::open for [libX11] (posix,linux): call dlopen on [libX11.so]
INFO | SharedLibrary::open for [libX11] failed (posix). dlerror: []
WARNING: could not open libX11.so, try libX11.so.6
INFO | SharedLibrary::open for [libX11.so.6]
INFO | SharedLibrary::open for [libX11.so.6]: not found in map, open for the first time
INFO | SharedLibrary::open for [libX11.so.6] (posix): begin
INFO | SharedLibrary::open for [libX11.so.6] (posix,linux): call dlopen on [libX11.so.6]
INFO | Initializing VkEmulation features:
INFO | glInteropSupported: false
INFO | useDeferredCommands: true
INFO | createResourceWithRequirements: true
INFO | useVulkanComposition: false
INFO | useVulkanNativeSwapchain: false
INFO | enable guestRenderDoc: false
INFO | ASTC LDR emulation mode: 2
INFO | enable ETC2 emulation: true
INFO | enable Ycbcr emulation: false
INFO | guestVulkanOnly: false
INFO | useDedicatedAllocations: false
INFO | Graphics Adapter Vendor Google (Google Inc.)
INFO | Graphics Adapter Android Emulator OpenGL ES Translator (Google SwiftShader)
INFO | Graphics API Version OpenGL ES 3.0 (OpenGL ES 3.0 SwiftShader 4.0.0.1)
INFO | Graphics API Extensions GL_OES_EGL_sync GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_depth24 GL_OES_depth32 GL_OES_element_index_uint GL_OES_texture_float GL_OES_texture_float_linear GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth_texture GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_packed_depth_stencil GL_OES_vertex_half_float GL_OES_standard_derivatives GL_OES_texture_npot GL_OES_rgb8_rgba8 GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888
INFO | Graphics Device Extensions N/A
INFO | Sending adb public key [QAAAAMnkPcqHisjHTuxq6LjnYCZe/t94GbzuBYzjGX2lmwpzd0h+zID48+HtcPNBZemclKa3+pktj9A53QgFnVHqfQBLqcgC/Ze0GW9iS+otyHWDjsI03BD48YLbVJIr6W7RbeKQAsnyi9iCRhgQFGEfsmuUr8oeAtOyT1ekiXHa6OcHlviJQS7/J2q1BQf/yedmWier/7STFAbGCUotbE/HOB24lkXf66hspSc5SlEF2B4T0/G0h9mfOW1hofr4zPH/Czm1Kcv3Yk6HWxQxkPm8Ngr6HmF6RGxpY3IOUrcQxkIxdh6CYiNPWzQ8xqvATraqlnnazCFvxZ8ycdCtk7aZuagIF9KppqHq3m3wZKSbA6VpTKgIkMVFOWuIY3/4xhdUwYHU+SuYWj0liR9AruTPRTA4EEKKswUl8lZQTZ60fGELfth2LIqvYqTIjSg3l7W4GJq5/3OnSCS2ctwsnyFW6utdPZCaxTkzxwJdYTweKMLL0e0cST75WE+23WybDuuxz7j4NcKXaE9isRhpaGhcf4NNW5AS9WIVCB3fnS3507DwaUKVWEUVyzkYF2fdWClaOmXaGWOOPrMXGAQUfcyuYWscgZbqB7sHB9mxDM415nuoxJh4WdroyGFUsrs6QJ999xm27SIgCyMofQHKR0qo6NbmEYK0qXz23o4IMHOISFYQ4SsLhAEAAQA= @unknown]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
WARNING: cannnot unmap ptr 0x7f807c354000 as it is in the protected range from 0x7f807c354000 to 0x7f80fc554000
WARNING: cannnot unmap ptr 0x7f80fc401000 as it is in the protected range from 0x7f807c354000 to 0x7f80fc554000
INFO | Monitoring duration of emulator setup.
WARNING | Using fallback path for the emulator registration directory.
WARNING | The emulator now requires a signed jwt token for gRPC access! Use the -grpc flag if you really want an open unprotected grpc port
INFO | Using security allow list from: /sdk/emulator/lib/emulator_access.json
WARNING | *** Basic token auth should only be used by android-studio ***
INFO | The active JSON Web Key Sets can be found here: /home/mobiledevops/.android/avd/running/18/jwks/be706db0-c561-41dd-bcf7-69d1b382c6a3/active.jwk
INFO | Scanning /home/mobiledevops/.android/avd/running/18/jwks/be706db0-c561-41dd-bcf7-69d1b382c6a3 for jwk keys.
INFO | Started GRPC server at 127.0.0.1:8554, security: Local, auth: +token
WARNING | Using fallback path for the emulator registration directory.
INFO | Advertising in: /home/mobiledevops/.android/avd/running/pid_18.ini
INFO | Setting display: 0 configuration to: 1080x1920, dpi: 420x420
INFO | setDisplayActiveConfig 0
##############################################################################
## WARNING - ACTION REQUIRED ##
## Consider using the '-metrics-collection' flag to help improve the ##
## emulator by sending anonymized usage data. Or use the '-no-metrics' ##
## flag to bypass this warning and turn off the metrics collection. ##
## In a future release this warning will turn into a one-time blocking ##
## prompt to ask for explicit user input regarding metrics collection. ##
## ##
## Please see '-help-metrics-collection' for more details. You can use ##
## '-metrics-to-file' or '-metrics-to-console' flags to see what type of ##
## data is being collected by emulator as part of usage statistics. ##
##############################################################################
INFO | Loading snapshot 'default_boot'...
WARNING | Failed to process .ini file /home/mobiledevops/.android/emu-update-last-check.ini for reading.
WARNING | Device 'cache' does not have the requested snapshot 'default_boot'
WARNING | Failed to load snapshot 'default_boot'
USER_WARNING | The saved emulator state could not be loaded, performing a cold boot.
qemu-system-x86_64-headless: Unable to connect character device modem: address resolution failed for ::1:43107: Name or service not known
WARNING | Failed to process .ini file /home/mobiledevops/.android/emu-update-last-check.ini for reading.
INFO | Activated packet streamer for bluetooth emulation
* daemon started successfully
root@d53760c05e4f:/app# adv devices
bash: adv: command not found
root@d53760c05e4f:/app# adb devices
List of devices attached
emulator-5554 device
It eventually starts and after trying to run the instrumented tests, I get this output:
BUILD SUCCESSFUL in 2m 10s
45 actionable tasks: 45 executed
root@d53760c05e4f:/app# ./gradlew connectedAndroidTest
[EmulatorConsole]: Failed to start Emulator console for 5554
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
> Task :app:connectedDebugAndroidTest
Skipping device 'emulator-5554' for ':app:': Unknown API Level
> : No compatible devices connected.[TestRunner] FAILED
Found 1 connected device(s), 0 of which were compatible.
Finished 1 tests on TestRunner
> Task :app:connectedDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:connectedDebugAndroidTest'.
> There were failing tests. See the report at: file:///app/app/build/reports/androidTests/connected/debug/index.html
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at .
BUILD FAILED in 26s
68 actionable tasks: 34 executed, 34 up-to-date
root@d53760c05e4f:/app#
Apparently the emulator from the docker container/image is not compatible, although I've created an emulator for Android 35 SDK.
This is the build.gradle.kts from inside the app directory of my Android project:
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
plugins {
id("com.android.application")
}
android {
namespace = "as.home.service"
compileSdk = 35
defaultConfig {
applicationId = "as.home.service"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags += "-std=c++17"
arguments += "-DANDROID_SDK_ROOT=${gradleLocalProperties(rootDir, providers).getProperty("sdk.dir")}"
arguments += "-DRUN_TESTS=OFF"
}
}
ndk {
abiFilters.add("armeabi-v7a") // 32-bit ARM
abiFilters.add("arm64-v8a") // 64-bit ARM
abiFilters.add("x86") // 32-bit x86
abiFilters.add("x86_64") // 64-bit x86
// Kotlin DSL syntax for adding ABI filters
}
}
signingConfigs {
create("release") {
storeFile = file("my-release-key.jks")
storePassword = "password"
keyAlias = "my-key-alias"
keyPassword = "password"
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path = file("../src/cpp/CMakeLists.txt")
version = "3.22.1"
}
}
ndkVersion = "27.1.12297006"
buildToolsVersion = "35.0.0"
buildFeatures.aidl = true;
}
dependencies {
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.test:rules:1.6.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
implementation ("androidx.test.ext:junit-gtest:1.0.0-alpha02")
implementation ("com.android.ndk.thirdparty:googletest:1.11.0-beta-1")
// JUnit 4 for Unit Testing
testImplementation("junit:junit:4.13.2")
// Mockito Core
testImplementation("org.mockito:mockito-core:5.14.2")
// Mockito JUnit Jupiter (optional for JUnit 5 integration)
testImplementation("org.mockito:mockito-junit-jupiter:5.14.2")
// AndroidX Test Core (optional for Android-specific tests)
androidTestImplementation("androidx.test:core:1.6.1")
// Optional for Mocking in Kotlin
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
// Optional MockK library (if needed)
testImplementation("io.mockk:mockk:1.13.13")
androidTestImplementation("androidx.test:rules:${rootProject.extra["rulesVersion"]}")
}
So does anyone with Android and Docker experience maybe knows what modifications should I do in order to run the Android Instrumented Tests on my Docker Container Android Emulator? Thank you for the patience of reading till here!
The Dockerfile for creating the image was made after finding this guide: /@iamdeepaksinghh/using-docker-and-gradle-to-build-an-android-project-92635cace3b3
I have an Android Studio project for an Android SDK 35, with an Emulator Android version 15. My project builds on the Android Studio IDE and also the Emulator from the IDE can run the Android Instrumented Tests.
I've build a Docker Image using this Dockerfile:
# Use the base image with Android SDK
FROM mobiledevops/android-sdk-image:latest
WORKDIR /app
USER root
# Set environment variables for Android SDK and AVD paths
ENV ANDROID_HOME=/sdk
ENV ANDROID_SDK_ROOT=/sdk
ENV ANDROID_AVD_HOME=/root/.android/avd
ENV PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$PATH"
# Download and install Android cmdline-tools
RUN mkdir -p $ANDROID_HOME/cmdline-tools && \
curl -o /cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip && \
unzip /cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools && \
mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest && \
rm /cmdline-tools.zip
# Install required SDK components
RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses && \
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install \
"cmdline-tools;latest" \
"platform-tools" \
"emulator" \
"platforms;android-35" \
"system-images;android-35;google_apis;x86_64"
# Create the AVD with x86_64 system image for API Level 35
RUN echo "no" | $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n testAVD -k "system-images;android-35;google_apis;x86_64" -d "pixel" --force
# Copy the project files into the container
COPY . .
# Add local.properties for SDK location
RUN echo "sdk.dir=$ANDROID_HOME" > local.properties
# Make the Gradle wrapper executable
RUN chmod +x ./gradlew
# Build the APK
RUN ./gradlew clean assembleRelease
# Default command for debugging (optional)
CMD ["/bin/bash"]
Docker image is created, however, when I start the container, after building the project and starting the emulator, when starting the emulator I get this output:
root@d53760c05e4f:/app# $ANDROID_HOME/emulator/emulator -avd testAVD -no-audio -no-window -accel off &
adb wait-for-device
[1] 18
* daemon not running; starting now at tcp:5037
INFO | Android emulator version 35.3.11.0 (build_id 12836668) (CL:N/A)
INFO | Graphics backend: gfxstream
INFO | Found systemPath /sdk/system-images/android-35/google_apis/x86_64/
INFO | Increasing RAM size to 2048MB
INFO | Checking system compatibility:
INFO | Checking: hasSufficientDiskSpace
INFO | Ok: Disk space requirements to run avd: `testAVD` are met.
INFO | Checking: hasSufficientHwGpu
INFO | Ok: Hardware GPU requirements to run avd: `testAVD` are passed.
INFO | Checking: hasSufficientSystem
INFO | Ok: System requirements to run avd: `testAVD` are met.
WARNING | File System is not ext4, disable QuickbootFileBacked feature
WARNING | x86_64 emulation may not work without hardware acceleration!
INFO | Storing crashdata in: /tmp/android-unknown/emu-crash-35.3.11.db, detection is enabled for process: 18
WARNING | Your GPU drivers may have a bug. Switching to software rendering.
library_mode swangle_indirect gpu mode swangle_indirect
INFO | Initializing hardware OpenGLES emulation support
I0207 10:48:05.764774 18 opengles.cpp:285] android_startOpenglesRenderer: gpu info
I0207 10:48:05.764903 18 opengles.cpp:286]
INFO | Not raising nofile soft limit from 1048576.
INFO | HealthMonitor disabled.
INFO | initIcdPaths: ICD set to 'swiftshader', using Swiftshader ICD
INFO | Setting ICD filenames for the loader = /sdk/emulator/qemu/linux-x86_64/lib64/vulkan/vk_swiftshader_icd.json:/sdk/emulator/lib64/vulkan/vk_swiftshader_icd.json
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] (posix,linux): call dlopen on [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so] failed (posix). dlerror: []
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] (posix,linux): call dlopen on [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1]
INFO | SharedLibrary::open for [/sdk/emulator/qemu/linux-x86_64/lib64/vulkan/libvulkan.so.1] failed (posix). dlerror: []
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so]
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so] (posix): begin
INFO | SharedLibrary::open for [/sdk/emulator/lib64/vulkan/libvulkan.so] (posix,linux): call dlopen on [/sdk/emulator/lib64/vulkan/libvulkan.so]
INFO | Added library: /sdk/emulator/lib64/vulkan/libvulkan.so
INFO | Selecting Vulkan device: SwiftShader Device (Subzero), Version: 1.3.0
INFO | Supports id properties, got a vulkan device UUID
INFO | SharedLibrary::open for [libGLESv2.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [libGLESv2.so] (posix): begin
INFO | SharedLibrary::open for [libGLESv2.so] (posix,linux): call dlopen on [libGLESv2.so]
INFO | SharedLibrary::open for [libEGL.so]: not found in map, open for the first time
INFO | SharedLibrary::open for [libEGL.so] (posix): begin
INFO | SharedLibrary::open for [libEGL.so] (posix,linux): call dlopen on [libEGL.so]
INFO | SharedLibrary::open for [libX11]
INFO | SharedLibrary::open for [libX11]: not found in map, open for the first time
INFO | SharedLibrary::open for [libX11] (posix): begin
INFO | SharedLibrary::open for [libX11] (posix,linux): call dlopen on [libX11.so]
INFO | SharedLibrary::open for [libX11] failed (posix). dlerror: []
WARNING: could not open libX11.so, try libX11.so.6
INFO | SharedLibrary::open for [libX11.so.6]
INFO | SharedLibrary::open for [libX11.so.6]: not found in map, open for the first time
INFO | SharedLibrary::open for [libX11.so.6] (posix): begin
INFO | SharedLibrary::open for [libX11.so.6] (posix,linux): call dlopen on [libX11.so.6]
INFO | Initializing VkEmulation features:
INFO | glInteropSupported: false
INFO | useDeferredCommands: true
INFO | createResourceWithRequirements: true
INFO | useVulkanComposition: false
INFO | useVulkanNativeSwapchain: false
INFO | enable guestRenderDoc: false
INFO | ASTC LDR emulation mode: 2
INFO | enable ETC2 emulation: true
INFO | enable Ycbcr emulation: false
INFO | guestVulkanOnly: false
INFO | useDedicatedAllocations: false
INFO | Graphics Adapter Vendor Google (Google Inc.)
INFO | Graphics Adapter Android Emulator OpenGL ES Translator (Google SwiftShader)
INFO | Graphics API Version OpenGL ES 3.0 (OpenGL ES 3.0 SwiftShader 4.0.0.1)
INFO | Graphics API Extensions GL_OES_EGL_sync GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_depth24 GL_OES_depth32 GL_OES_element_index_uint GL_OES_texture_float GL_OES_texture_float_linear GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth_texture GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_packed_depth_stencil GL_OES_vertex_half_float GL_OES_standard_derivatives GL_OES_texture_npot GL_OES_rgb8_rgba8 GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888
INFO | Graphics Device Extensions N/A
INFO | Sending adb public key [QAAAAMnkPcqHisjHTuxq6LjnYCZe/t94GbzuBYzjGX2lmwpzd0h+zID48+HtcPNBZemclKa3+pktj9A53QgFnVHqfQBLqcgC/Ze0GW9iS+otyHWDjsI03BD48YLbVJIr6W7RbeKQAsnyi9iCRhgQFGEfsmuUr8oeAtOyT1ekiXHa6OcHlviJQS7/J2q1BQf/yedmWier/7STFAbGCUotbE/HOB24lkXf66hspSc5SlEF2B4T0/G0h9mfOW1hofr4zPH/Czm1Kcv3Yk6HWxQxkPm8Ngr6HmF6RGxpY3IOUrcQxkIxdh6CYiNPWzQ8xqvATraqlnnazCFvxZ8ycdCtk7aZuagIF9KppqHq3m3wZKSbA6VpTKgIkMVFOWuIY3/4xhdUwYHU+SuYWj0liR9AruTPRTA4EEKKswUl8lZQTZ60fGELfth2LIqvYqTIjSg3l7W4GJq5/3OnSCS2ctwsnyFW6utdPZCaxTkzxwJdYTweKMLL0e0cST75WE+23WybDuuxz7j4NcKXaE9isRhpaGhcf4NNW5AS9WIVCB3fnS3507DwaUKVWEUVyzkYF2fdWClaOmXaGWOOPrMXGAQUfcyuYWscgZbqB7sHB9mxDM415nuoxJh4WdroyGFUsrs6QJ999xm27SIgCyMofQHKR0qo6NbmEYK0qXz23o4IMHOISFYQ4SsLhAEAAQA= @unknown]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
WARNING: cannnot unmap ptr 0x7f807c354000 as it is in the protected range from 0x7f807c354000 to 0x7f80fc554000
WARNING: cannnot unmap ptr 0x7f80fc401000 as it is in the protected range from 0x7f807c354000 to 0x7f80fc554000
INFO | Monitoring duration of emulator setup.
WARNING | Using fallback path for the emulator registration directory.
WARNING | The emulator now requires a signed jwt token for gRPC access! Use the -grpc flag if you really want an open unprotected grpc port
INFO | Using security allow list from: /sdk/emulator/lib/emulator_access.json
WARNING | *** Basic token auth should only be used by android-studio ***
INFO | The active JSON Web Key Sets can be found here: /home/mobiledevops/.android/avd/running/18/jwks/be706db0-c561-41dd-bcf7-69d1b382c6a3/active.jwk
INFO | Scanning /home/mobiledevops/.android/avd/running/18/jwks/be706db0-c561-41dd-bcf7-69d1b382c6a3 for jwk keys.
INFO | Started GRPC server at 127.0.0.1:8554, security: Local, auth: +token
WARNING | Using fallback path for the emulator registration directory.
INFO | Advertising in: /home/mobiledevops/.android/avd/running/pid_18.ini
INFO | Setting display: 0 configuration to: 1080x1920, dpi: 420x420
INFO | setDisplayActiveConfig 0
##############################################################################
## WARNING - ACTION REQUIRED ##
## Consider using the '-metrics-collection' flag to help improve the ##
## emulator by sending anonymized usage data. Or use the '-no-metrics' ##
## flag to bypass this warning and turn off the metrics collection. ##
## In a future release this warning will turn into a one-time blocking ##
## prompt to ask for explicit user input regarding metrics collection. ##
## ##
## Please see '-help-metrics-collection' for more details. You can use ##
## '-metrics-to-file' or '-metrics-to-console' flags to see what type of ##
## data is being collected by emulator as part of usage statistics. ##
##############################################################################
INFO | Loading snapshot 'default_boot'...
WARNING | Failed to process .ini file /home/mobiledevops/.android/emu-update-last-check.ini for reading.
WARNING | Device 'cache' does not have the requested snapshot 'default_boot'
WARNING | Failed to load snapshot 'default_boot'
USER_WARNING | The saved emulator state could not be loaded, performing a cold boot.
qemu-system-x86_64-headless: Unable to connect character device modem: address resolution failed for ::1:43107: Name or service not known
WARNING | Failed to process .ini file /home/mobiledevops/.android/emu-update-last-check.ini for reading.
INFO | Activated packet streamer for bluetooth emulation
* daemon started successfully
root@d53760c05e4f:/app# adv devices
bash: adv: command not found
root@d53760c05e4f:/app# adb devices
List of devices attached
emulator-5554 device
It eventually starts and after trying to run the instrumented tests, I get this output:
BUILD SUCCESSFUL in 2m 10s
45 actionable tasks: 45 executed
root@d53760c05e4f:/app# ./gradlew connectedAndroidTest
[EmulatorConsole]: Failed to start Emulator console for 5554
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
[PropertyFetcher]: ShellCommandUnresponsiveException getting properties for device emulator-5554
java.lang.Throwable: ShellCommandUnresponsiveException getting properties for device emulator-5554
at com.android.ddmlib.PropertyFetcher.handleException(PropertyFetcher.java:259)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:213)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$18(DeviceImpl.java:891)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:755)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeRemoteCommand$15(DeviceImpl.java:618)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeRemoteCommand(DeviceImpl.java:615)
at com.android.ddmlib.internal.DeviceImpl.lambda$executeShellCommand$13(DeviceImpl.java:557)
at com.android.ddmlib.internal.DeviceImpl.logRun1(DeviceImpl.java:1801)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:554)
at com.android.ddmlib.PropertyFetcher$1.run(PropertyFetcher.java:209)
> Task :app:connectedDebugAndroidTest
Skipping device 'emulator-5554' for ':app:': Unknown API Level
> : No compatible devices connected.[TestRunner] FAILED
Found 1 connected device(s), 0 of which were compatible.
Finished 1 tests on TestRunner
> Task :app:connectedDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:connectedDebugAndroidTest'.
> There were failing tests. See the report at: file:///app/app/build/reports/androidTests/connected/debug/index.html
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 26s
68 actionable tasks: 34 executed, 34 up-to-date
root@d53760c05e4f:/app#
Apparently the emulator from the docker container/image is not compatible, although I've created an emulator for Android 35 SDK.
This is the build.gradle.kts from inside the app directory of my Android project:
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
plugins {
id("com.android.application")
}
android {
namespace = "as.home.service"
compileSdk = 35
defaultConfig {
applicationId = "as.home.service"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags += "-std=c++17"
arguments += "-DANDROID_SDK_ROOT=${gradleLocalProperties(rootDir, providers).getProperty("sdk.dir")}"
arguments += "-DRUN_TESTS=OFF"
}
}
ndk {
abiFilters.add("armeabi-v7a") // 32-bit ARM
abiFilters.add("arm64-v8a") // 64-bit ARM
abiFilters.add("x86") // 32-bit x86
abiFilters.add("x86_64") // 64-bit x86
// Kotlin DSL syntax for adding ABI filters
}
}
signingConfigs {
create("release") {
storeFile = file("my-release-key.jks")
storePassword = "password"
keyAlias = "my-key-alias"
keyPassword = "password"
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path = file("../src/cpp/CMakeLists.txt")
version = "3.22.1"
}
}
ndkVersion = "27.1.12297006"
buildToolsVersion = "35.0.0"
buildFeatures.aidl = true;
}
dependencies {
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.test:rules:1.6.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
implementation ("androidx.test.ext:junit-gtest:1.0.0-alpha02")
implementation ("com.android.ndk.thirdparty:googletest:1.11.0-beta-1")
// JUnit 4 for Unit Testing
testImplementation("junit:junit:4.13.2")
// Mockito Core
testImplementation("org.mockito:mockito-core:5.14.2")
// Mockito JUnit Jupiter (optional for JUnit 5 integration)
testImplementation("org.mockito:mockito-junit-jupiter:5.14.2")
// AndroidX Test Core (optional for Android-specific tests)
androidTestImplementation("androidx.test:core:1.6.1")
// Optional for Mocking in Kotlin
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
// Optional MockK library (if needed)
testImplementation("io.mockk:mockk:1.13.13")
androidTestImplementation("androidx.test:rules:${rootProject.extra["rulesVersion"]}")
}
So does anyone with Android and Docker experience maybe knows what modifications should I do in order to run the Android Instrumented Tests on my Docker Container Android Emulator? Thank you for the patience of reading till here!
The Dockerfile for creating the image was made after finding this guide: https://medium.com/@iamdeepaksinghh/using-docker-and-gradle-to-build-an-android-project-92635cace3b3
Share Improve this question asked yesterday MrJayMrJay 393 bronze badges1 Answer
Reset to default 0These issues need to be fixed:
WARNING | x86_64 emulation may not work without hardware acceleration!
WARNING | Your GPU drivers may have a bug. Switching to software rendering.
library_mode swangle_indirect gpu mode swangle_indirect
Which means ...
a) provide hardware acceleration within Docker, when there is a GPU present on the host:
- https://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration
b) or run the emulator
headless by appending switch -no-window
(eg. when running remotely).
c) maybe try running an x86
instead of x86_64
image, if available.
Command emulator --help
would show all available command-line switches.
On a second look, it's probably meant to be JavaVersion.VERSION_17
and the Dockerfile
likely is NOT meant to build the package. I also have such android-builder image
, which I use without NDK or emulator.
Building the package with the Dockerfile
might only bloat the container with Gradle caches.
Creating the AVD could also be done at runtime, in order to avoid eventual bloating due to it.