Android Project Setup
This guide covers setting up an Android Blinc project — toolchain, build commands, and the platform-specific files (AndroidManifest.xml, Gradle config, debugging).
For the cross-platform Blinc API (native bridge, camera, deep linking, lifecycle, etc.), see the Mobile Development overview.
Prerequisites
1. Android SDK & NDK
# macOS
brew install --cask android-studio
export ANDROID_HOME=$HOME/Library/Android/sdk
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/26.1.10909125
export PATH=$PATH:$ANDROID_HOME/platform-tools
2. Rust Targets
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add x86_64-linux-android
cargo install cargo-ndk
Building
# Debug — single arch
cargo ndk -t arm64-v8a build
# Release — multi-arch
cargo ndk -t arm64-v8a -t armeabi-v7a build --release
# Or via Gradle (from platforms/android/)
./gradlew assembleDebug
The APK lands in app/build/outputs/apk/debug/app-debug.apk.
Project Configuration
Cargo.toml
[lib]
name = "my_app"
crate-type = ["cdylib", "staticlib"]
[target.'cfg(target_os = "android")'.dependencies]
blinc_app = { version = "0.5", features = ["android"] }
blinc_platform_android = "0.5"
android-activity = { version = "0.6", features = ["native-activity"] }
log = "0.4"
android_logger = "0.14"
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
<!-- Permissions for native bridge features -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="My App"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"
android:hardwareAccelerated="true">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="true"
android:launchMode="singleTask">
<meta-data
android:name="android.app.lib_name"
android:value="my_app" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Deep link: myapp://path/to/route -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
</activity>
</application>
</manifest>
Debugging
# View Rust logs
adb logcat | grep -E "(blinc|BlincApp)"
# Filter for native bridge calls
adb logcat | grep BlincNativeBridge
Common Issues
“Library not found” — ensure the native library is built and copied to app/src/main/jniLibs/<arch>/:
cargo ndk -t arm64-v8a build
cp target/aarch64-linux-android/debug/libmy_app.so \
platforms/android/app/src/main/jniLibs/arm64-v8a/
“Vulkan not supported” — check device capability:
adb shell getprop ro.hardware.vulkan
API 24+ devices generally support Vulkan, but some emulators may not.
“Native call failed” — verify the namespace+name matches between Kotlin and Rust handlers. Check logcat for BlincNativeBridge: handler not found for X.Y.
Touch events not working — verify the render context is created successfully and android.app.lib_name in the manifest matches your library name.
Performance
[profile.release]
lto = "fat"
opt-level = "z" # optimize for size on mobile
panic = "abort"
strip = true
codegen-units = 1
- Test on real devices — emulators have different GPU characteristics
- Profile with Android Studio Profiler for CPU/GPU/memory
- Bundle assets via
assets/—AndroidAssetLoaderauto-resolves them through the platformAssetLoadertrait
Next Steps
- Mobile Development overview — native bridge, camera, deep linking, lifecycle, safe area APIs
- iOS Project Setup — build the iOS counterpart
- CLI Reference