代码之家  ›  专栏  ›  技术社区  ›  Andromeda

改造无法从模型类解析json

  •  1
  • Andromeda  · 技术社区  · 6 年前

    我正在尝试在我的应用程序中显示这个json,使用网络调用更新。 样本数据:

    {
        total: 17727,
        total_pages: 1773,
        results: [ 
            {
                id: "qX9Ie7ieb1E",
                created_at: "2016-01-26T08:17:45-05:00",
                updated_at: "2018-05-18T13:04:07-04:00",
                width: 4956,
                height: 3304,
                color: "#101617",
                description: "Neon mural of woman wearing sunglasses and pink lipstick on brick wall in England",
                urls: { raw: "", regular: "", full: "", small:"", thumb:""}
            }, 
            {}, {}, ...
        ]
    }
    

    我已经创建了如下界面:

    public interface ApiService {
    
        @GET("search/photos")
        Call<ImagesResponse> getImages(
            @Query("client_id") String clientId,
            @Query("order_by") String orderBy,
            @Query("query") String query,
            @Query("page") int pageIndex
        );
    
    }
    

    以及API:

    public class UnsplashImageApi {
    
        public static Retrofit retrofit = null;
    
        private static OkHttpClient getOkHttpClient() {
            return new OkHttpClient.Builder()
                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                .build();
        }
    
        public static Retrofit getRetrofitClient() {
            if (retrofit != null) {
                return new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .baseUrl(Constants.UNSPLASH_BASE_URL)
                    .build();
            }
            return retrofit;
        }
    
    }
    

    模型类的结构基于如下响应:

    public class ImagesResponse {
    
        @Expose
        @SerializedName("total")
        private Integer total;
    
        @Expose
        @SerializedName("total_pages")
        private Integer totalPages;
    
        @Expose
        @SerializedName("results")
        private List<Results> imagesList = new ArrayList<>();
    

    为了简洁,省略了getter和setter。这个 Results 类显示如下:

    public class Results {
    
        @Expose
        @SerializedName("id")
        public String imageId;
    
        @Expose
        @SerializedName("raw")
        public String rawImg;
    
        @Expose
        @SerializedName("full")
        public String fullImg;
    
        @Expose
        @SerializedName("regular")
        public String regularImg;
    
        @Expose
        @SerializedName("small")
        public String smallImg;
    
        @Expose
        @SerializedName("thumb")
        public String thumbImg;
    
        public boolean isFavorite;
    

    在我的片段中,我试着调用 ApiService 加载第一页数据,如下所示:

    apiService = UnsplashImageApi.getRetrofitClient().create(ApiService.class);
    loadFirstPage();
    

    但应用程序在这条线上崩溃了 getRetrofitClient().create() 使用此错误日志:

    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object retrofit2.Retrofit.create(java.lang.Class)' on a null object reference
        at com.jjoey.walpy.fragments.ArtFragment.onCreateView(ArtFragment.java:70)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2346)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1428)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
    

    我省略了加载第一页的代码,因为这里不关心它。有谁能告诉我为什么它会崩溃并给出一个可能的解决方案吗?谢谢

    2 回复  |  直到 6 年前
        1
  •  0
  •   Avijit Karmakar    6 年前

    你写的 retrofit != null 在if条件下。

    public static Retrofit getRetrofitClient(){
        if (retrofit != null) { // Check this line
            return new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .baseUrl(Constants.UNSPLASH_BASE_URL)
                    .build();
        }
        return retrofit;
    }
    

    你得写信 retrofit == null 在if条件下。否则,改装将无法初始化。

    第一次翻新是空的,你已经检查过了 改装!=空 那么。这就是为什么if条件中的代码被忽略,并且在调用时它正在创建空指针异常 create() 方法,该方法来自改装的未初始化实例。

    修改后的代码为:

    public static Retrofit getRetrofitClient(){
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .baseUrl(Constants.UNSPLASH_BASE_URL)
                    .build();
        }
        return retrofit;
    }
    
        2
  •  0
  •   veritas1    6 年前

    你有一个npe,因为你的单例逻辑是不正确的。调整版本如下:

    public static Retrofit getRetrofitClient(){
        if (null == retrofit){
            retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getOkHttpClient())
                    .baseUrl(Constants.UNSPLASH_BASE_URL)
                    .build();
        }
        return retrofit;
    }