2015-09-07 142 views
16

我目前正在检查我的应用程序是否支持M。我在改造API调用时遇到此错误。这似乎是我得到的json错误。还有其他人遇到它吗?这是我的JSON助手类。Android M + Retrofit + JSON:无法使字段构造函数可访问

public class JsonHelper { 

    private static final String JSON_PARSE_ERROR = "Unable to parse JSON: "; 
    private static Gson sGson; 
    private static Gson sExposeGson; 

    static { 
     GsonBuilder builder = new GsonBuilder(); 
     builder.registerTypeAdapterFactory(new EnumTypeAdapterFactory()); 
     builder.registerTypeAdapter(BlogCategoryDto.class, new BlogCategorySerializer()); 
     ... 

     sGson = builder.create(); 

     builder.excludeFieldsWithoutExposeAnnotation(); 
     sExposeGson = builder.create(); 
    } 

    public static Gson getGson() { 
     return sGson; 
    } 

    public static Gson getsExposeGsonGson() { 
     return sExposeGson; 
    } 

    public static String toJson(@NonNull Object object) { 
     return sGson.toJson(object); 
    } 

    public static String toJson(@NonNull Object object, @NonNull Type type) { 
     return sGson.toJson(object, type); 
    } 

    public static String toExposeJson(@NonNull Object object) { 
     return sExposeGson.toJson(object); 
    } 

    public static String toExposeJson(@NonNull Object object, @NonNull Type type) { 
     return sExposeGson.toJson(object, type); 
    } 

    public static <T> T fromJson(@NonNull String content, @NonNull Class<T> clazz) 
      throws IllegalStateException { 
     try { 
      return sGson.fromJson(content, clazz); 
     } catch (JsonSyntaxException e) { 
      throw new IllegalStateException(JSON_PARSE_ERROR + content, e); 
     } 
    } 

    public static <T> T fromJson(@NonNull String content, @NonNull Type type) 
      throws IllegalStateException { 
     try { 
      return sGson.fromJson(content, type); 
     } catch (JsonSyntaxException e) { 
      throw new IllegalStateException(JSON_PARSE_ERROR + content, e); 
     } 
    } 
} 

这是抛出

D/Retrofit﹕java.lang.SecurityException: Can't make field constructor accessible 
     at java.lang.reflect.Constructor.setAccessible(Constructor.java:334) 
     at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:97) 
     at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:79) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:82) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:52) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:122) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:92) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:91) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:142) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:83) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:122) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:92) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:91) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:142) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:83) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:52) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:122) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:92) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:91) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:142) 
     at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:83) 
     at com.google.gson.Gson.getAdapter(Gson.java:359) 
     at com.google.gson.Gson.fromJson(Gson.java:809) 
     at com.google.gson.Gson.fromJson(Gson.java:775) 
     at retrofit.converter.GsonConverter.fromBody(GsonConverter.java:63) 
     at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:367) 
     at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) 
     at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278) 
     at retrofit.CallbackRunnable.run(CallbackRunnable.java:42) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
     at retrofit.Platform$Android$2$1.run(Platform.java:142) 
     at java.lang.Thread.run(Thread.java:818) 
+4

有一个在GSON项目已经开了一个问题:https://github.com/google/gson/issues/648 –

+0

不自动改装包括GSON?你为什么要使用自定义的Json厂? – Smashing

+0

@EfeKahraman你的权利似乎有一个问题那里 – Eoin

回答

23

正如指出的评论有在GSON项目媒体链接打开的问题的错误。

https://github.com/google/gson/issues/648

所以它似乎是一个好主意,等待,直到他们更新自己的图书馆。同时,我可以通过添加一行代码来快速解决问题。

static { 
    GsonBuilder builder = new GsonBuilder(); 

    ... 

    builder.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC);** 
    builder.excludeFieldsWithoutExposeAnnotation(); 
    sExposeGson = builder.create(); 
} 
+1

我试过这个,现在它没有崩溃在这一点上,但它给我的对象中的所有空值,因为真正的JSON响应中有非空值。任何想法? – Khawar

+1

由于您的模型没有'@ Expose'注释 – mrroboaat

+0

删除_builder.excludeFieldsWithoutExposeAnnotation(); _如果不是必需的。 – BaiJiFeiLong

0

中有版本的Android M使用Retrofit2一个问题,因为在here

解决方案的一个提到是配置GsonConverterFactory这样的:

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl(URLWebService) 
    .addConverterFactory(GsonConverterFactory.create(
          new GsonBuilder() 
          .excludeFieldsWithoutExposeAnnotation() 
          .create() 
         )) 
    .client(okHttpClient) 
    .build(); 
3

这为我工作。希望这可以帮助某人。

GsonBuilder builder = new GsonBuilder(); 
builder.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC); 
Gson gson = builder.create(); 
1

最好的方法!

GsonBuilder builder = new GsonBuilder().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC); 
    Gson gson = builder.create(); 
    Retrofit retrofit = new Retrofit.Builder().baseUrl(URL) 
     .addConverterFactory(GsonConverterFactory.create(gson)) 
     .build();