From 0c8279710e3cbba159163d0036e8cfb472999647 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 May 2026 11:21:33 +0000 Subject: [PATCH] fix: add (IntPtr, JniHandleOwnership) constructor to OsuGameActivity to fix JNI activation crash Agent-Logs-Url: https://github.com/winnerspiros/osu/sessions/0a7096f4-e29c-4d75-a84b-5d7de0b80ff1 Co-authored-by: winnerspiros <1675249+winnerspiros@users.noreply.github.com> --- osu.Android/OsuGameActivity.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index f308ace2d056..f17ea4835d4a 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -98,6 +98,8 @@ protected override osu.Framework.Game CreateGame() // The explicit SDL3-CS attribute roots SDLActivity(IntPtr, JniHandleOwnership) — the actual // overload TypeManager.Activate calls — which has NO managed call-graph path and would // otherwise be silently trimmed even if the parameterless constructor chain is preserved. + // See also the OsuGameActivity(IntPtr, JniHandleOwnership) constructor below, which is the + // direct fix for the v2026.509.229 crash: TypeManager.Activate needs this on the concrete type. [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors, "osu.Framework.Android.AndroidGameActivity", "osu.Framework.Android")] [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors, @@ -107,6 +109,19 @@ public OsuGameActivity() game = new OsuGameAndroid(this); } + // Required JNI activation constructor. TypeManager.Activate performs a reflection + // lookup for (IntPtr, JniHandleOwnership) on the *concrete* managed type when Android + // re-instantiates this Activity from a JNI handle (process death/recreation, back-stack + // restore). Inheriting this constructor from AndroidGameActivity/SDLActivity is not + // sufficient — .NET Android's TypeManager resolves it via GetConstructor on the concrete + // type; if the method is absent there the lookup falls through and Activate throws + // NotSupportedException ("Could not activate JNI Handle ... as managed type + // 'osu.Android.OsuGameActivity'"), which is the crash seen in v2026.509.229. + protected OsuGameActivity(IntPtr javaReference, JniHandleOwnership transfer) + : base(javaReference, transfer) + { + } + protected override void OnCreate(Bundle? savedInstanceState) { // NOTE: do NOT assign RequestedOrientation here. The `[Activity]` attribute on this