Android使用Retrofit获取MySQL数据时触发空指针异常求助
Hey there, let's break down why you're running into that NullPointerException and how to fix it. The error tells us you're trying to iterate over a List<LikelyProblems> that's null—this almost always happens when response.body() returns null, even if your API works in Postman. Let's go through the fixes step by step:
1. Add Defensive Checks for the Response and List
Right now you're directly accessing response.body() without verifying if the request was successful or if the list itself exists. Update your onResponse method to add these critical checks:
@Override public void onResponse(Call<List<LikelyProblems>> call, Response<List<LikelyProblems>> response) { // First confirm the request returned a successful status code (2xx) if (response.isSuccessful()) { List<LikelyProblems> likelyProblems = response.body(); // Only iterate if the list is not null and has items if (likelyProblems != null && !likelyProblems.isEmpty()) { for (LikelyProblems l : likelyProblems) { Log.d("id", l.getId()); Log.d("category", l.getCategory()); Log.d("Problems", l.getProblems()); } } else { Log.d("API Info", "No problems returned from the server"); Toast.makeText(getApplicationContext(), "No data available", Toast.LENGTH_SHORT).show(); } } else { // Handle non-successful responses (like 404, 500 errors) Log.d("API Error", "Request failed with code: " + response.code()); Toast.makeText(getApplicationContext(), "Request failed: " + response.code(), Toast.LENGTH_SHORT).show(); } }
2. Add a No-Argument Constructor to Your Model Class
Gson (the converter you're using) requires a no-argument constructor to properly instantiate your LikelyProblems objects. Your current model only has a parameterized constructor, which can cause parsing failures that result in a null response body. Update your model:
public class LikelyProblems { private String id; private String category; private String problems; // Add this empty constructor (critical for Gson parsing) public LikelyProblems() {} public LikelyProblems(String id, String category, String problems) { this.id = id; this.category = category; this.problems = problems; } // Getters remain unchanged public String getId() { return id; } public String getCategory() { return category; } public String getProblems() { return problems; } }
3. Verify Your API Response Matches the Expected Format
Double-check the JSON your API returns in Postman:
- If it's a direct array like
[{"id":"1","category":"Engine","problems":"..."}, ...], your current interface is correct. - If it's an object wrapping the array (common in REST APIs) like
{"data": [{"id":"1", ...}]}—you need to create a wrapper model to match this structure:
Create a Wrapper Model:
public class ProblemsResponse { // Match the exact key from your API response (e.g., "data" or "problems") private List<LikelyProblems> data; public List<LikelyProblems> getData() { return data; } }
Update Your Interface:
public interface LikelyProblemsClient { String BASE_URL = "http://192.168.1.35:85/tranxavApi/public/api/"; @GET("vehicle-problems") Call<ProblemsResponse> getProblems(); }
Update the Retrofit Call Handling:
Call<ProblemsResponse> call = likelyProblemsClient.getProblems(); call.enqueue(new Callback<ProblemsResponse>() { @Override public void onResponse(Call<ProblemsResponse> call, Response<ProblemsResponse> response) { if (response.isSuccessful()) { ProblemsResponse responseBody = response.body(); if (responseBody != null) { List<LikelyProblems> likelyProblems = responseBody.getData(); if (likelyProblems != null && !likelyProblems.isEmpty()) { // Iterate over the list as before } } } } @Override public void onFailure(Call<ProblemsResponse> call, Throwable t) { // Handle failure (see step 4 below) } });
4. Fix the Toast in onFailure
You forgot to call show() on your Toast, so you won't see any failure messages when something goes wrong. Update that:
@Override public void onFailure(Call<List<LikelyProblems>> call, Throwable t) { Log.e("API Failure", "Error fetching data", t); Toast.makeText(getApplicationContext(), "Failed to load data: " + t.getMessage(), Toast.LENGTH_SHORT).show(); }
These changes should resolve the NullPointerException by ensuring you handle null cases properly, fix parsing issues, and align your code with your API's actual response format.
内容的提问来源于stack exchange,提问作者oshabz

