You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit二次请求失败及调用WordPress API获图片数据返回null求助

Hey there! Let's fix those Retrofit headaches

I know 3 days stuck on these issues must be frustrating—let's break this down and get your code working properly.


First up: Why getImageRetrofit() returns null

The core issue here is how you're passing the image URL to your Retrofit interface. Let's look at what's happening:

  1. You're grabbing tempImageHref as a full URL (like https://your-site.com/wp-json/wp/v2/media/123) from the post response.
  2. Your interface uses @GET("{id}") with @Path("id")—this tells Retrofit to append the full URL string directly to your base URL, resulting in a broken URL like https://your-site.com/https://your-site.com/wp-json/wp/v2/media/123.

Fix steps:

1. Update your Retrofit interface

Replace the getImageInfo method with one that uses @Url instead of @Path—this lets you pass the full URL directly, skipping base URL拼接:

public interface RetrofitArrayApi {
    @GET("wp-json/wp/v2/posts?per_page=4")
    Call<List<WPPost>> getPostInfo();

    // Use @Url to accept full image URLs
    @GET
    Call<List<WPPostImage>> getImageInfo(@Url String imageHref);
}

2. Verify your WPPostImage model

Double-check that your WPPostImage class matches the exact structure of WordPress's media API response. If field names don't line up (e.g., WordPress uses guid but your model uses imageUrl), add @SerializedName annotations to map them correctly.


Second issue: First request works, second doesn't

The main culprit here is creating a new Retrofit instance every time you call getRetrofit() or getImageRetrofit(). This wastes resources (like OkHttp connection pools) and can cause unexpected connection failures on subsequent calls.

Fix steps:

1. Create a singleton Retrofit instance

Make a reusable Retrofit instance instead of instantiating it repeatedly:

private Retrofit retrofit;

private Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        // Optional: Add a logging interceptor to debug requests/responses
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

2. Update your request methods to use the singleton

Modify getRetrofit() and getImageRetrofit() to use the shared instance:

private void getRetrofit() {
    // Clear the list before loading new data to avoid duplicates
    list.clear();
    
    RetrofitArrayApi service = getRetrofitInstance().create(RetrofitArrayApi.class);
    Call<List<WPPost>> call = service.getPostInfo();
    
    call.enqueue(new Callback<List<WPPost>>() {
        @Override
        public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
            Log.e("Latest","response: "+response.body());
            if (response.body() == null) {
                Log.e("Error", "Post response body is null");
                return;
            }
            
            for (int i=0; i<response.body().size(); i++) {
                WPPost post = response.body().get(i);
                Log.e("main ","title "+post.getTitle().getRendered() + " " + post.getId() );
                
                String tempDate = post.getDate().replace("T"," ");
                String tempImageHref = post.getLinks().getWpFeaturedmedia().get(0).getHref();
                String link = post.getLink();
                
                Log.e("Href", "onResponse: "+tempImageHref);
                Log.e("PostLink",link);
                
                getImageRetrofit(tempImageHref);
                list.add(new LatestModel(
                    post.getTitle().getRendered(),
                    tempDate,
                    tempImageHref,
                    LatestModel.IMAGE_TYPE,
                    link
                ) );
            }
            adapter.notifyDataSetChanged();
        }
        
        @Override
        public void onFailure(Call<List<WPPost>> call, Throwable t) {
            t.printStackTrace();
        }
    });
}

private void getImageRetrofit(String imageHref) {
    Log.e("getImageRetrofit","called "+imageHref);
    RetrofitArrayApi service = getRetrofitInstance().create(RetrofitArrayApi.class);
    Call<List<WPPostImage>> callImage = service.getImageInfo(imageHref);
    
    callImage.enqueue(new Callback<List<WPPostImage>>() {
        @Override
        public void onResponse(Call<List<WPPostImage>> call, Response<List<WPPostImage>> response) {
            Log.e("ImageInfo","info: "+response.body());
            // Tip: Since this is async, update your list item here once you have the image data
            // and call adapter.notifyItemChanged(position) to refresh the UI
        }
        
        @Override
        public void onFailure(Call<List<WPPostImage>> call, Throwable t) {
            Log.e("Link Failed", t.getMessage());
            t.printStackTrace();
        }
    });
}

Extra tips to avoid future issues

  • Always use a singleton for Retrofit/OkHttp instances to reuse connections and resources.
  • Add the OkHttp logging interceptor (as shown above) to see exactly what requests are being sent and responses received—this is invaluable for debugging.
  • When dealing with nested async requests (like fetching images after posts), track which post corresponds to which image request so you can update the UI correctly when the image data comes in.

内容的提问来源于stack exchange,提问作者Muhammad Arslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:03:11