翻新无法从模型类解析JSON

时间:2018-07-07 11:20:00

标签: android json retrofit2

我正在尝试通过网络调用的改进在我的应用程序中显示此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<>();

为简洁起见,省略了吸气剂和吸气剂。 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 个答案:

答案 0 :(得分:0)

您有一个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;
}

答案 1 :(得分:0)

您已在if条件中写了retrofit != null

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;
}

您必须在if条件下写retrofit == null。否则,翻新将不会初始化。

第一次翻新为空,然后您选中了retrofit != null。这就是为什么if条件中的代码被绕过,并在您从Retrofit的未初始化实例中调用create()方法时创建Null Pointer Exception的原因。

修改后的代码将是:

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