Retrofit2+RxJava在OnNext()中Model类返回null问题求助
List<Beans> Despite Valid HTTP Response Hi there, let's dig into why your List<Beans> is coming up null even though the HttpLoggingInterceptor shows a valid server response. Here are the most common fixes and checks to resolve this:
1. Fix Thread Scheduling Mix-Up (First Quick Win)
You’ve got your subscribeOn and observeOn reversed! This won’t directly cause a null list, but it can hide errors or lead to unexpected behavior:
// Wrong order client.getPosts("posts") .observeOn(Schedulers.newThread()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(observer); // Correct order client.getPosts("posts") .subscribeOn(Schedulers.io()) // Run network request on IO thread .observeOn(AndroidSchedulers.mainThread()) // Trigger callbacks on main thread .subscribe(observer);
2. Check Your Beans Class (Most Likely Culprit)
Gson can’t parse JSON into your Beans class if the structure doesn’t match. Here’s what to verify:
- Field Name Matching: Ensure your class fields exactly match the JSON keys, or use
@SerializedNameto map mismatched names.
Example:public class Beans { // If JSON uses "post_id" instead of "id" @SerializedName("post_id") private int id; @SerializedName("post_content") private String content; // Critical: Gson requires a public no-arg constructor public Beans() {} // Add getters/setters (optional but recommended) public int getId() { return id; } public void setId(int id) { this.id = id; } } - No-Arg Constructor: Without this, Gson can’t instantiate your
Beansobjects, leading to a null list.
3. Log Parsing Errors (You’re Missing This!)
Your current onError method is empty—this is hiding critical exceptions that explain why parsing failed. Update it to log errors:
@Override public void onError(Throwable e) { e.printStackTrace(); // Print the full stack trace to Logcat Log.e("Saket", "Parsing error: " + e.getMessage()); }
This will immediately show you if Gson is throwing a JsonSyntaxException or similar.
4. Validate Raw JSON Response
To rule out parsing issues entirely, temporarily modify your interface to return raw ResponseBody and inspect the JSON directly:
// Updated interface public interface Posts { @GET("/typicode/demo/{path}") Observable<ResponseBody> getPosts(@Path("path") String path); } // Updated observer Observer<ResponseBody> observer = new Observer<ResponseBody>() { @Override public void onSubscribe(Disposable d) {} @Override public void onNext(ResponseBody value) { try { String rawJson = value.string(); Log.d("Saket", "Raw JSON: " + rawJson); // Try manual parsing to test List<Beans> testList = new Gson().fromJson( rawJson, new TypeToken<List<Beans>>(){}.getType() ); Log.d("Saket", "Manual parse result: " + testList); } catch (IOException e) { e.printStackTrace(); } } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onComplete() {} };
This will confirm if the JSON structure matches what your Beans class expects.
5. Double-Check Retrofit BaseUrl + Path
Retrofit has strict rules for URL concatenation:
- If your
BASE_URLends with a/(e.g.,https://example.com/), your@GETpath should not start with/(use@GET("typicode/demo/{path}")instead of@GET("/typicode/demo/{path}")). - If your
BASE_URLdoesn’t end with/, the@GETpath must start with/.
Since you see a valid response in logs, this is less likely, but it’s worth confirming to avoid edge cases.
内容的提问来源于stack exchange,提问作者samsap

