问题
I'm working in an App with Unity3D.
Im using my own utilities DLL with some classes.
I've been working for months now, and made lots of builds/compilations with no problem.
Last week added a new class to the DLL, it worked well in my PC but when I builded the project and used it in my Android device it stopped working. The Android Monitor program shows me that error:
"Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types"
The types that Newtonsoft can find constructors for, are the new classes I added recently.
Important: All the other classes are deserialized with no errors.
The only different think that the new class has is the namespace and the type. Variables, methods and constructors still the same.
It is also important that the project works fine on PC, the problem only occurs in Android.
I know I can do some custom deserializers or add tags, etc.. to my class. But the thing is that only that class causes the problem and it is no reason to change the JSon deserialization system.
Thank you.
回答1:
Background: This is a common problem that roots from the UnityLinker's bytecode stripping algorithms. What's happening is that the UnityLinker cannot see any use of your types constructor (as Newtonsoft.Json only uses it via reflection, which a compiler cannot foresee), so it removes it. This bytecode stripping is only activated when building with the IL2CPP scripting backend, which is why you didn't experience any problem when building on your PC (or any other solely using Mono for that matter).
The fix: To overcome this, you can disable bytecode stripping for that type (or even just for that constructor). You can do this using a link.xml
file. Example:
<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>
I've written some helpful pages on using link.xml
among other tools to cope with AOT issues, as I find Unity's documentation to be lacking and scattered:
https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/Fix-AOT-using-link.xml
To read more about why this is, please refer to my explanation page: https://github.com/jilleJr/Newtonsoft.Json-for-Unity/wiki/What-even-is-AOT
回答2:
Applejag's answer is the correct one (link.xml or AotHelper), but I have an alternative. A lazy one. :)
Check your 'Managed Stripping Level' within Unity's player settings for iOS and for Android. Mine was set to High and when I switched to Low it resolved the issue. Granted, there are some repercussions to file size for that, but if you are working in a small app like myself then it is not an issue.
回答3:
You can have an empty constructor in class in order to de-serialize it.
You can try putting this in your class:
[Runtime.Preserve(AllMembers = true)]
来源:https://stackoverflow.com/questions/59757635/how-to-solve-newtonsoft-json-jsonserializationexception-unable-to-find-construc