2015-09-07 138 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();