Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android crash - no non-static method CustomUnityPlayer;.hidePreservedContent() #926

Open
timbotimbo opened this issue Feb 15, 2024 · 3 comments
Labels
android This issue is specific to the Android Platform. bug This issue refers to a bug in the plugin Unity issue/bug Problem caused by Unity that we can't fix on our end.

Comments

@timbotimbo
Copy link
Collaborator

timbotimbo commented Feb 15, 2024

Description

This bug was first described in a larger issue #903, I'm just splitting it into a separate issue specific to this error.

On some Unity versions, android devices on Android 8 or lower will immediately crash when Unity is started.
(See more logs at the bottom)

java.lang.NoSuchMethodError: no non-static method "Lcom/xraph/plugin/flutter_unity_widget/CustomUnityPlayer;.hidePreservedContent()V"

Breaking change

I tested multiple Unity versions to find the exact version that breaks this.

The crash starts at Unity 2021.3.31 and 2022.3.10.
Both these versions have this entry in the changelog, that seems like the culprit.

  • Android: Show the last rendered frame when the application come back from the pause state. (UUM-30881)

Reproduction

  1. Build and run any project using this plugin, like the example.
  2. Click through the app until Unity launches in Flutter app.
  3. On Android <= 8 and the specified Unity versions, it will instantly crash.

Possible workaround

As noted in the original issue #903:

Adding the missing function signature to CustomUntityPlayer.kt in the plugin prevents the crash.

class CustomUnityPlayer(context: Activity, upl: IUnityPlayerLifecycleEvents?) : UnityPlayer(context, upl) {

+     // define a function with the correct name
+    fun hidePreservedContent() {
+        // do nothing here for now
+    }    

}

However this causes the last paused frame to show when closing and reopening a page with the unitywidget.

Trying to call something like super.hidePreservedContent results in

Cannot access 'hidePreservedContent': it is private in 'UnityPlayer'

So we might be able to call this private function using reflection.

Versions

❌ indicates a crash.

Unity:
2021.3.21 ✔
2021.3.28 ✔
2021.3.30 ✔
2021.3.31 ❌
2021.3.34 ❌
2021.3.35 ❌
2021.3.36 ❌

2022.3.0 ✔
2022.3.9 ✔
2022.3.10 ❌
2022.3.14 ❌
2022.3.15 ❌
2022.3.18 ❌
2022.3.19 ✔
2022.3.20 ✔

Android:
Android 6 ❌
Android 7.1.2 ❌
Android 8 ❌ (reported)
Android 9 ✔
Android 13 ✔

Devices:
This seems to happen on any device on Android <= 8.

  • Samsung Galaxy J5, Android 6
  • Wileyfox Swift, Android 7
  • (reported) Huawei Mate 10 Lite, Android 8
  • (reported) Samsung Galaxy S7

Logs

Log Unity 2021.3.31, Android 6
E/AndroidRuntime( 8176): FATAL EXCEPTION: UnityMain
E/AndroidRuntime( 8176): Process: com.xraph.plugin.flutter_unity_widget_example, PID: 8176
E/AndroidRuntime( 8176): java.lang.Error: FATAL EXCEPTION [UnityMain]
E/AndroidRuntime( 8176): Unity version     : 2021.3.31f1
E/AndroidRuntime( 8176): Device model      : Wileyfox Wileyfox Swift
E/AndroidRuntime( 8176): Device fingerprint: Wileyfox/Swift/crackling:7.1.2/N2G48B/eeea277114:user/release-keys
E/AndroidRuntime( 8176): Build Type        : Release
E/AndroidRuntime( 8176): Scripting Backend : IL2CPP
E/AndroidRuntime( 8176): ABI               : arm64-v8a
E/AndroidRuntime( 8176): Strip Engine Code : true
E/AndroidRuntime( 8176): 
E/AndroidRuntime( 8176): Caused by: java.lang.NoSuchMethodError: no non-static method "Lcom/xraph/plugin/flutter_unity_widget/CustomUnityPlayer;.hidePreservedContent()V"
E/AndroidRuntime( 8176): 	at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
E/AndroidRuntime( 8176): 	at com.unity3d.player.UnityPlayer.access$500(Unknown Source)
E/AndroidRuntime( 8176): 	at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source)
E/AndroidRuntime( 8176): 	at android.os.Handler.dispatchMessage(Handler.java:98)
Log Unity 2022.3.10, Android 7
E/AndroidRuntime(10917): FATAL EXCEPTION: UnityMain
E/AndroidRuntime(10917): Process: com.xraph.plugin.flutter_unity_widget_example, PID: 10917
E/AndroidRuntime(10917): java.lang.Error: FATAL EXCEPTION [UnityMain]
E/AndroidRuntime(10917): Unity version     : 2022.3.10f1
E/AndroidRuntime(10917): Device model      : Wileyfox Wileyfox Swift
E/AndroidRuntime(10917): Device fingerprint: Wileyfox/Swift/crackling:7.1.2/N2G48B/eeea277114:user/release-keys
E/AndroidRuntime(10917): CPU supported ABI : [arm64-v8a, armeabi-v7a, armeabi]
E/AndroidRuntime(10917): Build Type        : Release
E/AndroidRuntime(10917): Scripting Backend : IL2CPP
E/AndroidRuntime(10917): Libs loaded from  : lib/arm64
E/AndroidRuntime(10917): Strip Engine Code : true
E/AndroidRuntime(10917): 
E/AndroidRuntime(10917): Caused by: java.lang.NoSuchMethodError: no non-static method "Lcom/xraph/plugin/flutter_unity_widget/CustomUnityPlayer;.hidePreservedContent()V"
E/AndroidRuntime(10917): 	at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
E/AndroidRuntime(10917): 	at com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(Unknown Source)
E/AndroidRuntime(10917): 	at com.unity3d.player.UnityPlayer$D$a.handleMessage(Unknown Source)
E/AndroidRuntime(10917): 	at android.os.Handler.dispatchMessage(Handler.java:98)
E/AndroidRuntime(10917): 	at android.os.Looper.loop(Looper.java:154)
E/AndroidRuntime(10917): 	at com.unity3d.player.UnityPlayer$D.run(Unknown Source)
@timbotimbo timbotimbo added bug This issue refers to a bug in the plugin android This issue is specific to the Android Platform. unity breaking change labels Feb 15, 2024
@timbotimbo
Copy link
Collaborator Author

I just noticed that the 'workaround' caused a bug that Unity won't stop showing away the last paused frame, even on Android 13. This confirms that the Show the last rendered frame when the application come back from the pause state fix is the cause.

I have updated the issue above.

@timbotimbo
Copy link
Collaborator Author

timbotimbo commented Feb 16, 2024

Using reflection seem to fix it. (tested on Android 7 and 13).

// CustomUnityplayer.kt
import java.lang.reflect.Method


     // Unity 2021.3.31+ and 2022.3.10+ try to call this private function, which throws an error on Android <= 8. https://github.com/juicycleff/flutter-unity-view-widget/issues/926
     fun hidePreservedContent() {
        Log.i(LOG_TAG, "hidePreservedContent")

        // manually call the private function using reflection.
        UnityPlayer::class.java.declaredMethods
        .find { it.name == "hidePreservedContent" }
        ?.let {
            it.isAccessible = true
            it.invoke(this)
        }
    
     }

https://github.com/timbotimbo/flutter-unity-view-widget/tree/hide_preserved_content

@timbotimbo
Copy link
Collaborator Author

Looks like this is 'fixed' in Unity starting with 2022.3.19.
There are however no changes the the changelog that explain it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android This issue is specific to the Android Platform. bug This issue refers to a bug in the plugin Unity issue/bug Problem caused by Unity that we can't fix on our end.
Projects
None yet
Development

No branches or pull requests

1 participant