You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity Newtonsoft JSON安卓IL2CPP打包ReferenceConverter构造方法缺失报错

异常根因

这个异常是IL2CPP构建的固有特性触发的:

Unity执行IL2CPP构建时会默认对.NET基础类库执行未使用代码裁剪,编辑器下使用Mono运行时不会执行裁剪逻辑,所以运行正常。Newtonsoft.Json反序列化接口类型的属性时,会尝试调用System.ComponentModel.ReferenceConverter处理类型转换,这个类默认会被IL2CPP裁剪,导致运行时找不到构造方法抛出异常。

解决方案

以下方案按实施成本从低到高排序:

  • 方案1:添加裁剪配置保留缺失类
    在Assets目录下新建名为link.xml的文件,写入以下内容即可,无需修改业务代码:

    <linker>
      <assembly fullname="System">
        <type fullname="System.ComponentModel.ReferenceConverter" preserve="all"/>
      </assembly>
    </linker>
    
  • 方案2:修改属性类型避免接口转换
    直接把IpLocationData的属性从接口类型改为具体实现类类型,从根源避免Newtonsoft调用ReferenceConverter:

    public class IpLocationData : IIpLocationData
    {
        public IpLocationData(ConnectionData connection, CurrencyData currency, LocationData location, bool success, TimeData time)
        {
            ConnectionData = connection;
            CurrencyData = currency;
            LocationData = location;
            Success = success;
            TimeData = time;
        }
    
        [JsonProperty("connection")]
        public ConnectionData ConnectionData { get; }
        [JsonProperty("currency")]
        public CurrencyData CurrencyData { get; }
        [JsonProperty("location")]
        public LocationData LocationData { get; }
        [JsonProperty("success")]
        public bool Success { get; }
        [JsonProperty("time")]
        public TimeData TimeData { get; }
    
        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
    

    这个方案修改量小,运行效率最高。

  • 方案3:保留接口设计,自定义类型转换器
    如果你需要保留接口抽象的架构设计,可以实现通用的接口转实现类转换器,替代系统的ReferenceConverter:
    首先实现转换器类:

    public class ConcreteTypeConverter<TInterface, TImplementation> : JsonConverter<TInterface> where TImplementation : TInterface
    {
        public override void WriteJson(JsonWriter writer, TInterface value, JsonSerializer serializer)
        {
            serializer.Serialize(writer, value);
        }
    
        public override TInterface ReadJson(JsonReader reader, Type objectType, TInterface existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            return serializer.Deserialize<TImplementation>(reader);
        }
    }
    

    然后给每个接口属性绑定对应的转换器:

    [JsonProperty("connection")]
    [JsonConverter(typeof(ConcreteTypeConverter<IConnectionData, ConnectionData>))]
    public IConnectionData ConnectionData { get; }
    
    [JsonProperty("currency")]
    [JsonConverter(typeof(ConcreteTypeConverter<ICurrencyData, CurrencyData>))]
    public ICurrencyData CurrencyData { get; }
    
    // 剩余两个接口属性同理配置即可
    
验证方法

如果不确定是否是裁剪导致的问题,可以临时把Unity PlayerSettings里的Managed Stripping Level调整为Disabled,构建测试如果不再报错,就可以确认是裁剪问题,再选择对应方案处理即可,不建议长期禁用裁剪,会导致包体大幅增大。

内容的提问来源于stack exchange,提问作者Стас Рыжов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:45:02