Open timbotimbo opened 5 months ago
Narrowed it down to this commit on Flutter master. Which includes the engine PR Platform channel for predictive back in route transitions on android
With some custom plugin modifications I managed to try this on Unity 2023.2.20 and 6000.0.7.
6000.0.7 even has a Predictive Back Support
toggle in the player settings.
I'm still getting the same error, so I will probably have to open an issue in the Flutter repo.
2023.2.20
E/Unity (17280): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity (17280): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity (17280): at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method)
E/Unity (17280): at java.lang.reflect.Method.getReturnType(Method.java:148)
E/Unity (17280): at java.lang.Class.getDeclaredMethods(Class.java:1880)
E/Unity (17280): at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26)
E/Unity (17280): at com.unity3d.player.UnityPlayerForActivityOrService.nativeRender(Native Method)
E/Unity (17280): at com.unity3d.player.S.handleMessage(Unknown Source:140)
E/Unity (17280): at android.os.Handler.dispatchMessage(Handler.java:102)
E/Unity (17280): at android.os.Looper.loop(Looper.java:214)
E/Unity (17280): at com.unity3d.player.V.run(Unknown Source:24)
E/Unity (17280): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[
6000
E/Unity ( 8521): AndroidJavaException: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity ( 8521): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/window/OnBackInvokedCallback;
E/Unity ( 8521): at java.lang.reflect.Executable.getMethodReturnTypeInternal(Native Method)
E/Unity ( 8521): at java.lang.reflect.Method.getReturnType(Method.java:148)
E/Unity ( 8521): at java.lang.Class.getDeclaredMethods(Class.java:1880)
E/Unity ( 8521): at com.unity3d.player.ReflectionHelper.getMethodID(Unknown Source:26)
E/Unity ( 8521): at com.unity3d.player.UnityPlayerForActivityOrService.nativeRender(Native Method)
E/Unity ( 8521): at com.unity3d.player.v0.handleMessage(Unknown Source:140)
E/Unity ( 8521): at android.os.Handler.dispatchMessage(Handler.java:102)
E/Unity ( 8521): at android.os.Looper.loop(Looper.java:214)
E/Unity ( 8521): at com.unity3d.player.x0.run(Unknown Source:24)
E/Unity ( 8521): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.window.OnBackInvokedCallback" on path: DexPathList[[zip file "/data/app/com....
After a report in the Flutter repo this can be labeled as a Unity issue.
Once AR boots up, Unity uses the getMethodID
function in the ReflectionHelper
class of unity-classes.jar
.
This function gets a list of all function in the current Activity using Java reflection getDeclaredMethods()
, and then tries to match function signatures.
It then repeats this for all super classes of the current Activity.
The getDeclaredMethods
call instantly crashes on Android <13 because it can't handle the OnBackInvokedCallback
return type that is defined in API 33.
Flutter won't stop using this class for a few people using the niche use-case of embedding Unity with AR. So AR is broken from now on unless this can be fixed on the Unity side.
With some luck a try-catch around getDeclaredMethods
might be enough.
However this means either:
I've tried to decompile unity-classes.jar, but none of the decompilers that I could find returned valid code that could compile again without errors.
To replicate this issue witthout Flutter:
import android.annotation.TargetApi;
import android.window.OnBackInvokedCallback;
@TargetApi(33)
protected OnBackInvokedCallback getOnBackInvokedCallback() {
return null;
}
AR is broken with Flutter 3.22+. Don't expect this to be fixed for months, if at all.
Thanks again for your tireless and meticulous work tracking all of this @timbotimbo it's very much appreciated. I've added a note to the README for this issue.
This is now in the Unity issue tracker.
They seem to have omitted most details from my bug report, but I guess it is a first step.
Anyone affect by this should probably upvote this in the issuetracker.
Unity got back to me on the bug report, calling it "By Design".
Given that Flutter devs point me at Unity, and Unity considers it by design, AR is likely a lost cause on Android < 13.
[UPDATE]
This is now in the Unity issue tracker. Anyone affect by this should probably upvote this in the issuetracker.
Description
Since Flutter 3.22, Unity will crash on certain Android versions when ARFoundation is activated.
This only happens on Android <13. This might also affect other unity plugins using native code, I just noticed it using ARFoundation.
In my own project Unity works fine for 3D scenes but crashes when I switch to a scene that includes ARFoundation. In the example project here, Unity shows up with the Flutter logo but crashes once the AR support check runs.
Error in the console:
Looking up OnBackInvokedCallback, it is added in API 33 (android 13) and is related to the predictive back gesture in Android 14.
I'm not sure if this is a flutter bug where it sends some kind of message which it shouldn't on API <33, or if it is caused by Unity missing an implementation.
Error log
Full console log up to the crash
``` √ Built build\app\outputs\flutter-apk\app-debug.apk D/FlutterEmbedLog( 7029): onAttachedToEngine D/FlutterEmbedLog( 7029): onAttachedToActivity D/FlutterEmbedLog( 7029): Activity resumed, resuming Unity Connecting to VM Service at ws://127.0.0.1:1851/hE4igOjN93Y=/ws D/com.learntoflutter.flutter_embed_unity_android.platformView.UnityViewFactory@4db3836( 7029): UnityViewFactory creating view 0 I/IL2CPP ( 7029): JNI_OnLoad I/FlutterEmbedLog( 7029): Attached Unity to view I/FlutterEmbedLog( 7029): Attached Unity to new view D/FlutterEmbedLog( 7029): UnityPlatformView onFlutterViewAttached I/PlatformViewsController( 7029): Hosting view in a virtual display for platform view: 0 I/PlatformViewsController( 7029): PlatformView is using SurfaceTexture backend D/Dialog ( 7029): mIsSamsungBasicInteraction = false D/Dialog ( 7029): mIsSamsungBasicInteraction = false, isMetaDataInActivity = false D/vndksupport( 7029): Loading /vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl.so from current namespace instead of sphal namespace. I/DecorView( 7029): createDecorCaptionView >> DecorView@bdb2310[], isFloating: false, isApplication: false, hasWindowDecorCaption: false, hasWindowControllerCallback: false D/InputTransport( 7029): Input channel constructed: fd=96 D/ViewRootImpl@4eea71a[MainActivity]( 7029): setView = DecorView@bdb2310[MainActivity] TM=true MM=false D/ViewRootImpl@da5e15f[MainActivity]( 7029): Relayout returned: old=[0,0][720,1480] new=[0,0][720,1480] result=0x3 surface={valid=true 503242113024} changed=false V/InputMethodManager( 7029): Not IME target window, ignoring D/FlutterEmbedLog( 7029): UnityPlayerSingleton onWindowVisibilityChanged 0 D/FlutterEmbedLog( 7029): UnityPlayerSingleton became visible, so pausing and resuming Unity D/SurfaceView( 7029): onWindowVisibilityChanged(0) true com.unity3d.player.a{e296541 VFE...... ......I. 0,0-0,0 #7f05004f app:id/unitySurfaceView} of ViewRootImpl@4eea71a[MainActivity] D/ViewRootImpl@4eea71a[MainActivity]( 7029): dispatchAttachedToWindow D/ViewRootImpl@4eea71a[MainActivity]( 7029): Relayout returned: old=[0,0][720,788] new=[0,0][720,788] result=0x7 surface={valid=true 502678339584} changed=true D/mali_winsys( 7029): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000 D/OpenGLRenderer( 7029): eglCreateWindowSurface = 0x7509fc9b80, 0x7509f6c010 D/SurfaceView( 7029): show() Surface(name=SurfaceView - Sys2030:com.learntoflutter.flutter_embed_unity_example/com.learntoflutter.flutter_embed_unity_example.MainActivity@e296541@0[7029])/@0x5c01ae6 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceCreated 1 #8 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} D/SurfaceView( 7029): surfaceChanged (720,788) 1 #8 com.unity3d.player.a{e296541 VFE...... ......ID 0,0-720,788 #7f05004f app:id/unitySurfaceView} I/Unity ( 7029): MemoryManager: Using 'Dynamic Heap' Allocator. W/d_unity_exampl( 7029): Accessing hidden method Ljava/lang/invoke/MethodHandles$Lookup;->Flutter version
Crashed on:
Did not crash on:
Unity version
Only tested with: 2022.3.21f1, 2022.3.33f1 ArFoundation 5.1.2 and 5.1.4
Minimum reproducible example
flutter_embed_unity
folder from this repoexample_unity_2022_3_project
folder from this repo. The only change applied to build the example was to change the android sdk to 34 in the gradle files.Any project using AR with android <13 will likely work to trigger this.
Android devices
Devices without crash:
Devices with crash:
Some things I've tried
-keep class android.window.** { *; }
-keep class android.window.OnBackInvokedCallback { *; }
.android:enableOnBackInvokedCallback="false"
to all androidmanifest activities and applications.implementation "androidx.activity:activity:1.6.0
in gradle (OnbackInvokedCallback is mentioned in the changes.)