juicycleff / flutter-unity-view-widget

Embeddable unity game engine view for Flutter. Advance demo here https://github.com/juicycleff/flutter-unity-arkit-demo
BSD 3-Clause "New" or "Revised" License
2.09k stars 505 forks source link

[Android] Fix Unity plugins using the AndroidJavaProxy. (mUnityPlayer error) #908

Closed timbotimbo closed 4 months ago

timbotimbo commented 6 months ago

Description

Unity made changes to their AndroidJavaProxy which causes a crash when using certain packages. This breaks popular Unity plugins like ARFoundation and Google Ads, and likely many more.

Unity expects a mUnityPlayer property to exist on the MainActivity, but the FlutterActivity used in Flutter apps doesn't have that property.

This change is found in the following Unity versions (and maybe more):

For the full description and discussion see https://github.com/juicycleff/flutter-unity-view-widget/issues/836

Error

Example of the error when the app crashes:

Non-fatal Exception: java.lang.Exception: AndroidJavaException : java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "mUnityPlayer" in class "Lcom/example/app/MainActivity;" or its superclasses
       at com.unity3d.player.UnityPlayer.nativeRender(com.unity3d.player.UnityPlayer)
       at com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(com.unity3d.player.UnityPlayer)
       at com.unity3d.player.UnityPlayer$C$a.handleMessage(com.unity3d.player.UnityPlayer$C$a)
       at android.os.Handler.dispatchMessage(android.os.Handler)
       at android.os.Looper.loopOnce(android.os.Looper)
       at android.os.Looper.loop(android.os.Looper)
       at com.unity3d.player.UnityPlayer$C.run(com.unity3d.player.UnityPlayer$C)
       at UnityEngine.AndroidJNISafe.CheckException(AndroidJNISafe.cs:24)
       at UnityEngine.AndroidJNISafe.GetFieldID(AndroidJNISafe.cs:87)
       at UnityEngine._AndroidJNIHelper.GetFieldID(AndroidJava.cs:1614)
       at UnityEngine.AndroidJNIHelper.GetFieldID(AndroidJNI.bindings.cs:91)
       at UnityEngine._AndroidJNIHelper.GetFieldID[ReturnType](AndroidJava.cs:1534)
       at UnityEngine.AndroidJNIHelper.GetFieldID[FieldType](AndroidJNI.bindings.cs:198)
       at UnityEngine.AndroidJavaObject._Get[FieldType](AndroidJava.cs:630)
       at UnityEngine.AndroidJavaObject.Get[FieldType](AndroidJava.cs:345)
       at UnityEngine.AndroidJNIHelper.CreateJavaProxy(AndroidJNI.bindings.cs:106)

Solution

This pull request adds a new class FlutterUnityActivity and interface IFlutterUnityActivity.
These contain a mUnityPlayer property that gets set by the plugin once Unity is initialized.

This does add a manual setup step, which i've added to the readme.

I've had some users use my branch since August 2023 and I haven't heard of any issues yet.

Type of Change

Merging

This can be merged with a squash merge, to hide the multiple documentation commits.