Skip to content

Commit 11c4af0

Browse files
authored
Merge pull request #321 from winnerspiros/copilot/fix-osu-android-crash-another-one
fix(android): add explicit JNI activation constructor to OsuGameActivity
2 parents a79ad46 + fb3717a commit 11c4af0

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

osu.Android/Linker.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,15 @@
102102
pass (where the .NET Android SDK does include it in the link set), ILLink finds
103103
the stored rule and preserves the assembly in full. Removing these entries
104104
"to silence the warnings" allows ILLink to freely trim JNI-only constructors
105-
from AndroidGameActivity, crashing the app on launch. -->
105+
from AndroidGameActivity, crashing the app on launch.
106+
107+
ADDITIONAL DEFENCE (v2026.508.227+): OsuGameActivity now also declares its own
108+
explicit (IntPtr, JniHandleOwnership) constructor that chains to base. Because
109+
osu.Android is unambiguously preserve="all" and is always resolvable at
110+
descriptor-processing time, this makes the JNI-activation constructor available
111+
in the concrete type regardless of whether the IL2007-deferred rule for
112+
osu.Framework.Android is honoured. The v2026.508.226 field crash confirmed
113+
that the deferred rule alone is not always sufficient. -->
106114
<assembly fullname="osu.Framework" preserve="all" />
107115
<assembly fullname="osu.Framework.Android" preserve="all" />
108116
<assembly fullname="ppy.Veldrid.SPIRV" preserve="all" />

osu.Android/OsuGameActivity.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ protected override osu.Framework.Game CreateGame()
8888
return game;
8989
}
9090

91+
// JNI activation constructor. Android's TypeManager.Activate resolves this
92+
// constructor via reflection when recreating the managed wrapper from a JNI
93+
// handle (e.g. after process restore or across configuration changes). Without
94+
// an explicit declaration here the linker might only find the inherited version
95+
// in osu.Framework.Android — an assembly that ILLink cannot resolve during
96+
// descriptor processing (IL2007), making the preserve="all" rule unreliable for
97+
// inherited members. Declaring it in osu.Android (which is unambiguously
98+
// preserve="all") guarantees the constructor survives trimming.
99+
protected OsuGameActivity(IntPtr handle, JniHandleOwnership transfer)
100+
: base(handle, transfer)
101+
{
102+
}
103+
91104
public OsuGameActivity()
92105
{
93106
game = new OsuGameAndroid(this);

0 commit comments

Comments
 (0)