not-fl3 / miniquad

Cross platform rendering in Rust
Apache License 2.0
1.55k stars 173 forks source link

Cannot run quad example in android #328

Open Mifom opened 1 year ago

Mifom commented 1 year ago

Hi. Thanks for such a cool project!

I'm building a game that uses macroquad and want to run it in android. But I have an issue when run it: android cannot find MainActivity.

It is reproduced when I try to build quad example from this repo.

Steps to reproduce: 1:

# from cargo-quad-apk
$ docker build . --tag builder
# from miniquad
$ docker run --rm -v $(pwd):/root/src -w /root/src -it builder cargo quad-apk build --release --example quad

2: Install target/android-artifacts/release/apk/examples/quad.apk to android device and run

not-fl3 commented 1 year ago

I've seen this error before, but I never managed to reproduced in either an emulator or any android devices I own :((

It shows up with samsung SM-G960U1 from google developer console and works perfectly fine on any other test devices they have

`Exception java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{rust.test/rust.test.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "rust.test.MainActivity" on path: ..`

getting a stable repro is usually the hardest part of fixing android-related problem, so I would be really happy for any tips on whats going on here

Mifom commented 1 year ago

I have this issue when running on Samsung Galaxy S7 and Xiaomi Redmi 4X with this apk: apk.zip

It was built using steps to reproduce.

I've also tried to analyze it through online java decompilers and they are successfully decompiling MainActivity.java file.

andreymal commented 1 year ago

I have the same error on my Redmi 4X (Android 6 / MIUI 8.2)

I find these lines in the log interesting:

16086 E dex2oat : Failed to create oat file: /data/dalvik-cache/arm64/data@app@rust.quad_test-1@base.apk@classes.dex: Permission denied
16086 I dex2oat : dex2oat took 621.823us (threads: 4) 
16071 W art     : Failed execv(/system/bin/dex2oat --runtime-arg -classpath --runtime-arg  --instruction-set=arm64 --instruction-set-features=smp,a53 --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --runtime-arg -Xms64m --runtime-arg -Xmx512m --instruction-set-variant=generic --instruction-set-features=default --dex-file=/data/app/rust.quad_test-1/base.apk --oat-file=/data/dalvik-cache/arm64/data@app@rust.quad_test-1@base.apk@classes.dex) because non-0 exit status
16071 W art     : Failed to open dex file '/data/app/rust.quad_test-1/base.apk' from memory: Unrecognized version number in /data/app/rust.quad_test-1/base.apk: 0 3 8

If I understand correctly, 0 3 8 corresponds to Android 8, which is too new for Redmi 4X

@not-fl3 I assume there is a need to tweak something in the docker container to make it create version 035 dex or older?

andreymal commented 1 year ago

I think I found the cause:

cargo-quad-apk/src/ops/build.rs:271:

        d8_cmd.arg("--min-api")
            .arg("26");

Replacing it with .arg(config.min_sdk_version.to_string()); fixed this error, but then I got another error:

18866 W linker  : /data/app/rust.quad_test-1/lib/arm64/libquad_test.so: is missing DT_SONAME will use basename as a replacement: "libquad_test.so"
18866 D AndroidRuntime: Shutting down VM
18866 E AndroidRuntime: FATAL EXCEPTION: main
18866 E AndroidRuntime: Process: rust.quad_test, PID: 18866
18866 E AndroidRuntime: java.lang.NoSuchFieldError: No instance field layoutInDisplayCutoutMode of type I in class Landroid/view/WindowManager$LayoutParams; or its superclasses (declaration of 'android.view.WindowManager$LayoutParams' appears in /system/framework/framework.jar:classes2.dex)
18866 E AndroidRuntime:     at rust.quad_test.MainActivity$1.run(MainActivity.java:247)
18866 E AndroidRuntime:     at android.app.Activity.runOnUiThread(Activity.java:5573)
18866 E AndroidRuntime:     at rust.quad_test.MainActivity.setFullScreen(MainActivity.java:240)
18866 E AndroidRuntime:     at quad_native.QuadNative.activityOnCreate(Native Method)

The documentation says that layoutInDisplayCutoutMode is "Added in API level 28", which is Android 9 (again, too new for Redmi 4X)

andreymal commented 1 year ago

After reverting https://github.com/not-fl3/miniquad/pull/312 I finally got a working apk

andreymal commented 1 year ago

Not really related to this issue, but too keep the conversation going I want to mention that https://github.com/not-fl3/miniquad/pull/401 broke compatibility with Android <= 10

(this PR is not trivial and I'm too lazy to figure out how to fix this, so I just pinned the miniquad version to https://github.com/not-fl3/miniquad/commit/0fa2e35d36266485a432176bd04204aab216e58d)