문제

I'm having trouble getting an application to work with full linking. This is my setup (my assembly names changed):

  • Mono for Android 4.4.54
  • An Android application (MyApp)
  • A platform-agnostic library (MyLib)

I'm attempting to deserialize a type (Person) from JSON text using ServiceStack.Text. It works fine when only linking SDK assemblies.

Rather than put linker include attributes in MyLib, I'm using a LinkDescription XML file in MyApp. It looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<linker>
  <assembly fullname="MyLib">
    <type fullname="MyLib.Person" preserve="fields">
      <method name=".ctor" />
    </type>
  </assembly>
</linker>

This is my logcat output:

E/MyApp(14494): InitialiseUser(): System.TypeInitializationException: An exception was thrown by the type initializer for ServiceStack.Text.Json.JsonReader`1 ---> System.ArgumentNullException: Argument cannot be null.
E/MyApp(14494): Parameter name: method
E/MyApp(14494):   at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure, Boolean allowClosed) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.PlatformExtensions.MakeDelegate (System.Reflection.MethodInfo mi, System.Type delegateType, Boolean throwOnBindFailure) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Json.JsonReader.GetParseFn (System.Type type) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Json.JsonTypeSerializer.GetParseFn (System.Type type) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Common.TypeAccessor.Create (ITypeSerializer serializer, ServiceStack.Text.TypeConfig typeConfig, System.Reflection.PropertyInfo propertyInfo) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Common.DeserializeTypeRef.GetTypeAccessorMap (ServiceStack.Text.TypeConfig typeConfig, ITypeSerializer serializer) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Common.DeserializeType`1[ServiceStack.Text.Json.JsonTypeSerializer].GetParseMethod (ServiceStack.Text.TypeConfig typeConfig) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Common.JsReader`1[ServiceStack.Text.Json.JsonTypeSerializer].GetCoreParseFn[Person] () [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Common.JsReader`1[ServiceStack.Text.Json.JsonTypeSerializer].GetParseFn[Person] () [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at ServiceStack.Text.Json.JsonReader`1[MyLib.Person]..cctor () [0x00000] in <filename unknown>:0 
E/MyApp(14494):   --- End of inner exception stack trace ---
E/MyApp(14494):   at ServiceStack.Text.JsonSerializer.DeserializeFromString[Person] (System.String value) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at MyLib.Person.FromJson (System.String json, Boolean throwOnNullOrEmpty) [0x00000] in <filename unknown>:0 
E/MyApp(14494):   at MyApp.MainActivity.InitialiseUser () [0x00000] in <filename unknown>:0 

After this, my instance of Person is null.

It seems from the output that the default constructor of Person can't be found (it has no explicitly defined constructor).

Any help is much appreciated.

도움이 되었습니까?

해결책 2

In the end I actually found more issues that I could not resolve via the code method in my previous answer. This is because some of the classes that the linker omitted were internal to the ServiceStack.Text assembly.

Ultimately I reverted back to using Link Description XML. It looked like this:

<?xml version="1.0" encoding="utf-8" ?>
<linker>
  <assembly fullname="ServiceStack.Text">
    <type fullname="ServiceStack.Text.Json.JsonReader`1" >
      <method name="GetParseFn" />
    </type>
    <type fullname="ServiceStack.Text.Common.DeserializeListWithElements`2" >
      <method name="ParseGenericList" />
    </type>
    <type fullname="ServiceStack.Text.Common.WriteListsOfElements`2" >
      <method name="WriteList" />
      <method name="WriteArray" />
    </type>
  </assembly>
</linker>

I blogged about how to achieve this here.

다른 팁

Indeed it was ServiceStack.Text itself being messed up by the linker. JsonReader<T>.GetParseFn() is accessed by reflection, evidently causing its omission.

I've done away with the Linker Description XML and I've added a class that looks like this:

using ServiceStack.Text.Common;
using ServiceStack.Text.Json;

namespace MyApp
{
    public class LinkerInclude
    {
        public ParseStringDelegate IncludeJsonReader<T>()
        {
            return JsonReader<T>.GetParseFn();
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top