Skip to content

Commit

Permalink
android - fix issues other than the rendering (#5130)
Browse files Browse the repository at this point in the history
# Objective

- Make Bevy work on android

## Solution

- Update android metadata and add a few more
- Set the target sdk to 31 as it will soon (in august) be the minimum sdk level for play store
- Remove the custom code to create an activity and use ndk-glue macro instead
- Delay window creation event on android
- Set the example with compatibility settings for wgpu. Those are needed for Bevy to work on my 2019 android tablet
- Add a few details on how to debug in case of failures
- Fix running the example on emulator. This was failing because of the name of the example

Bevy still doesn't work on android with this, audio features need to be disabled because of an ndk-glue version mismatch: rodio depends on 0.6.2, winit on 0.5.2. You can test with:
```
cargo apk run --release --example android_example --no-default-features --features "bevy_winit,render"
```
  • Loading branch information
mockersf committed Jun 30, 2022
1 parent 96f0ebb commit d4e4a92
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 36 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/validation-jobs.yml
Expand Up @@ -52,17 +52,14 @@ jobs:
target/
key: ${{ runner.os }}-cargo-build-android-${{ hashFiles('**/Cargo.toml') }}

- name: Uninstall android-31
run: $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --uninstall "platforms;android-31"

- name: Install Android targets
run: rustup target add aarch64-linux-android armv7-linux-androideabi

- name: Install Cargo APK
run: cargo install --force cargo-apk

- name: Build APK
run: cargo apk build --example android
run: cargo apk build --example android_example

run-examples-on-windows:
runs-on: windows-latest
Expand Down
13 changes: 8 additions & 5 deletions Cargo.toml
Expand Up @@ -1467,19 +1467,22 @@ hidden = true
# Android
[[example]]
crate-type = ["cdylib"]
name = "android"
name = "android_example"
path = "examples/android/android.rs"

[package.metadata.example.android]
[package.metadata.example.android_example]
hidden = true

[package.metadata.android]
apk_label = "Bevy Example"
package = "org.bevyengine.example"
apk_name = "bevyexample"
assets = "assets"
resources = "assets/android-res"
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
min_sdk_version = 16
target_sdk_version = 29

[package.metadata.android.sdk]
target_sdk_version = 31

[package.metadata.android.application]
icon = "@mipmap/ic_launcher"
label = "Bevy Example"
16 changes: 4 additions & 12 deletions crates/bevy_derive/src/bevy_main.rs
Expand Up @@ -10,19 +10,11 @@ pub fn bevy_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
);

TokenStream::from(quote! {
#[no_mangle]
// use ndk-glue macro to create an activity: https://github.com/rust-windowing/android-ndk-rs/tree/master/ndk-macro
#[cfg(target_os = "android")]
unsafe extern "C" fn ANativeActivity_onCreate(
activity: *mut std::os::raw::c_void,
saved_state: *mut std::os::raw::c_void,
saved_state_size: usize,
) {
bevy::ndk_glue::init(
activity as _,
saved_state as _,
saved_state_size as _,
main,
);
#[cfg_attr(target_os = "android", bevy::ndk_glue::main(backtrace = "on", ndk_glue = "bevy::ndk_glue"))]
fn android_main() {
main()
}

#[no_mangle]
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_winit/src/lib.rs
Expand Up @@ -48,9 +48,13 @@ impl Plugin for WinitPlugin {
#[cfg(target_arch = "wasm32")]
app.add_plugin(web_resize::CanvasParentResizePlugin);
let event_loop = EventLoop::new();
#[cfg(not(target_os = "android"))]
let mut create_window_reader = WinitCreateWindowReader::default();
#[cfg(target_os = "android")]
let create_window_reader = WinitCreateWindowReader::default();
// Note that we create a window here "early" because WASM/WebGL requires the window to exist prior to initializing
// the renderer.
#[cfg(not(target_os = "android"))]
handle_create_window_events(&mut app.world, &event_loop, &mut create_window_reader.0);
app.insert_resource(create_window_reader)
.insert_non_send_resource(event_loop);
Expand Down
29 changes: 22 additions & 7 deletions examples/README.md
Expand Up @@ -346,32 +346,47 @@ When using `NDK (Side by side)`, the environment variable `ANDROID_NDK_ROOT` mus
To run on a device setup for Android development, run:

```sh
cargo apk run --example android
cargo apk run --example android_example
```

:warning: At this time Bevy does not work in Android Emulator.

When using Bevy as a library, the following fields must be added to `Cargo.toml`:

```toml
[package.metadata.android]
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
target_sdk_version = 29
min_sdk_version = 16

[package.metadata.android.sdk]
target_sdk_version = 31
```

Please reference `cargo-apk` [README](https://crates.io/crates/cargo-apk) for other Android Manifest fields.

### Debugging

You can view the logs with the following command:

```sh
adb logcat | grep 'RustStdoutStderr\|bevy\|wgpu'
```

In case of an error getting a GPU or setting it up, you can try settings logs of `wgpu_hal` to `DEBUG` to get more informations.

Sometimes, running the app complains about an unknown activity. This may be fixed by uninstalling the application:

```sh
adb uninstall org.bevyengine.example
```

### Old phones

Bevy by default targets Android API level 29 in its examples which is the <!-- markdown-link-check-disable -->
Bevy by default targets Android API level 31 in its examples which is the <!-- markdown-link-check-disable -->
[Play Store's minimum API to upload or update apps](https://developer.android.com/distribute/best-practices/develop/target-sdk). <!-- markdown-link-check-enable -->
Users of older phones may want to use an older API when testing.

To use a different API, the following fields must be updated in Cargo.toml:

```toml
[package.metadata.android]
[package.metadata.android.sdk]
target_sdk_version = >>API<<
min_sdk_version = >>API or less<<
```
Expand Down
29 changes: 22 additions & 7 deletions examples/README.md.tpl
Expand Up @@ -98,32 +98,47 @@ When using `NDK (Side by side)`, the environment variable `ANDROID_NDK_ROOT` mus
To run on a device setup for Android development, run:

```sh
cargo apk run --example android
cargo apk run --example android_example
```

:warning: At this time Bevy does not work in Android Emulator.

When using Bevy as a library, the following fields must be added to `Cargo.toml`:

```toml
[package.metadata.android]
build_targets = ["aarch64-linux-android", "armv7-linux-androideabi"]
target_sdk_version = 29
min_sdk_version = 16

[package.metadata.android.sdk]
target_sdk_version = 31
```

Please reference `cargo-apk` [README](https://crates.io/crates/cargo-apk) for other Android Manifest fields.

### Debugging

You can view the logs with the following command:

```sh
adb logcat | grep 'RustStdoutStderr\|bevy\|wgpu'
```

In case of an error getting a GPU or setting it up, you can try settings logs of `wgpu_hal` to `DEBUG` to get more informations.

Sometimes, running the app complains about an unknown activity. This may be fixed by uninstalling the application:

```sh
adb uninstall org.bevyengine.example
```

### Old phones

Bevy by default targets Android API level 29 in its examples which is the <!-- markdown-link-check-disable -->
Bevy by default targets Android API level 31 in its examples which is the <!-- markdown-link-check-disable -->
[Play Store's minimum API to upload or update apps](https://developer.android.com/distribute/best-practices/develop/target-sdk). <!-- markdown-link-check-enable -->
Users of older phones may want to use an older API when testing.

To use a different API, the following fields must be updated in Cargo.toml:

```toml
[package.metadata.android]
[package.metadata.android.sdk]
target_sdk_version = >>API<<
min_sdk_version = >>API or less<<
```
Expand Down
11 changes: 10 additions & 1 deletion examples/android/android.rs
@@ -1,9 +1,18 @@
use bevy::prelude::*;
use bevy::{
prelude::*,
render::settings::{WgpuSettings, WgpuSettingsPriority},
};

// the `bevy_main` proc_macro generates the required android boilerplate
#[bevy_main]
fn main() {
App::new()
// This configures the app to use the most compatible rendering settings.
// They help with compatibilty with as many devices as possible.
.insert_resource(WgpuSettings {
priority: WgpuSettingsPriority::Compatibility,
..default()
})
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
Expand Down

0 comments on commit d4e4a92

Please sign in to comment.