Skip to content

[TrimmableTypeMap] UCO nctor should re-invoke ctor on Activatable/Replaceable peers #11179

@simonrozsival

Description

@simonrozsival

Summary

The UCO constructor callback (nctor_0_uco) skips activation entirely when ShouldSkipActivation returns true (peer exists and is not Activatable/Replaceable). However, when the peer IS Activatable or Replaceable, the UCO currently also skips — it should instead invoke the constructor on the existing peer instance.

Current behavior

// nctor_0_uco — skips if peer exists and is NOT Activatable/Replaceable
if (!WithinNewObjectScope && !ShouldSkipActivation(self))
{
    // create new instance via GetUninitializedObject + ctor
}
// Otherwise: return (no-op) — even for Activatable/Replaceable peers

Expected behavior

Should mirror ManagedPeer.Construct (lines 80-88, 117-119):

var self = PeekPeer(r_self);
if (self != null) {
    var state = self.JniManagedPeerState;
    if ((state & Activatable) != Activatable && (state & Replaceable) != Replaceable) {
        return; // skip — peer exists and is stable
    }
}
// ... later:
if (self != null) {
    cinfo.Invoke(self, pvalues); // re-invoke ctor on existing Activatable/Replaceable peer
    return;
}
// else: create new instance via ActivatePeer

The Activatable state is set by ConstructPeer and Replaceable is used for types like Application that may be replaced during process lifecycle. If such a type's nctor_0_uco is called, the constructor should be invoked on the existing instance rather than being silently skipped.

Impact

May affect Activity recreation after configuration changes or Application replacement. Needs investigation to determine if this code path is actually hit in practice for trimmable typemap apps.

Context

  • ManagedPeer.Construct reference: external/Java.Interop/src/Java.Interop/Java.Interop/ManagedPeer.cs:80-119
  • UCO emission: src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs EmitUcoConstructor
  • ShouldSkipActivation: src/Mono.Android/Java.Interop/JavaPeerProxy.cs:95-105

Part of #10788

Metadata

Metadata

Assignees

No one assigned

    Labels

    copilot`copilot-cli` or other AIs were used to author thistrimmable-type-map

    Type

    No fields configured for Bug.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions