如何解决“Newtonsoft.Json.JsonSerializationException 无法找到用于类型的构造函数”Android 错误?

Adá*_*aró 2 c# dll android json.net unity-game-engine

我正在使用 Unity3D 处理应用程序。

我在一些类中使用我自己的实用程序 DLL。

我已经工作了几个月,并且进行了大量构建/编译,没有任何问题。

上周向 DLL 添加了一个新类,它在我的 PC 中运行良好,但是当我构建该项目并在我的 Android 设备中使用它时,它停止工作。Android Monitor 程序向我显示了该错误:

“Newtonsoft.Json.JsonSerializationException 无法找到用于类型的构造函数”

Newtonsoft 可以找到构造函数的类型是我最近添加的新类。

重要提示:所有其他类都被反序列化,没有错误。

新类唯一不同的想法是命名空间类型。变量、方法和构造函数仍然相同。

该项目在 PC 上运行良好也很重要,该问题仅发生在 Android 中。

我知道我可以为我的班级做一些自定义反序列化程序或添加标签等。但问题是只有那个类会导致问题,没有理由更改 JSon 反序列化系统。

谢谢你。

App*_*jag 7

背景:这是一个常见问题,源于 UnityLinker 的字节码剥离算法。发生的事情是 UnityLinker 看不到您的类型构造函数的任何使用(因为 Newtonsoft.Json 仅通过反射使用它,编译器无法预见),因此它将其删除。此字节码剥离仅在使用 IL2CPP 脚本后端构建时激活,这就是为什么您在 PC(或任何其他仅使用 Mono 的情况下)构建时没有遇到任何问题的原因。

解决方法:为了克服这个问题,您可以禁用该类型的字节码剥离(甚至只是该构造函数)。您可以使用link.xml文件执行此操作。例子:

<linker>
    <assembly fullname="MyAssembly">
        <type fullname="MyAssembly.MyCSharpClass">
            <!-- disables stripping just for the constructor -->
            <method signature="System.Void .ctor()"/>
        </type>

        <!-- disables stripping for the entire type -->
        <type fullname="MyAssembly.MyCSharpClass" preserve="all" />
    </assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)

我写了一些关于使用link.xml其他工具来处理 AOT 问题的有用页面,因为我发现 Unity 的文档缺乏和分散:https : //github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Fix -AOT-using-link.xml

要详细了解这是为什么,请参阅我的解释页面:https : //github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/What-even-is-AOT


bob*_*uba 5

正如其他人提到的,发生这种情况是因为 il2cpp 上的统一代码剥离有点过于急切,并且删除了构造函数,因为它看不到它是否真正被使用。

除了此处建议的解决方案之外,还可以将其添加UnityEngine.Scripting.PreserveAttribute到空构造函数中。像这样:

using UnityEngine.Scripting;

[Preserve] // Ensures it survives code-stripping
public Response()
{
}
Run Code Online (Sandbox Code Playgroud)

我认为比使用 link.xml 更喜欢这种方式,因为它将与该类相关的所有内容保留在一个位置,而不是分布在多个文件中。