How to solve “Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types” Android error?

[亡魂溺海] 提交于 2021-01-28 05:15:00

问题


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:


  1. You can have an empty constructor in class in order to de-serialize it.

  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!