Retrofit + RxJava 结合POJO出现空指针异常,请求技术帮助
Hey there! Let's dig into that NullPointerException you're hitting with RxJava + Retrofit— I totally get how frustrating it is to comb through code and still miss the root cause. Let's break down the most likely culprits and how to debug them:
First, since your logs point to the response/POJO, let's start there and work outward:
1. POJO Null Safety Gaps
Even if you've checked your model, these easy-to-miss issues often cause NPEs:
- Primitive vs. wrapper types: If your API returns a null for a field you declared as a primitive (like
intinstead ofInteger), it'll throw an NPE—primitives can't hold null values. Swap to wrappers for any field that might be optional in the API response. - Missing null handling in converters: If you're using Gson or Moshi, make sure optional fields are marked appropriately. For Gson, you can use
@Nullable(with Jetpack annotations) or set up a default adapter to handle nulls. If your API returns a null for a field you assumed would always exist, your converter will leave it null, leading to crashes when you access it. - Mismatched field names: Double-check that your POJO's
@SerializedNamevalues exactly match the API's JSON keys. A typo here can leave fields null even if the API sends data.
2. RxJava Null Emission Rules
RxJava 2+ doesn't allow null emissions, which can cause hidden NPEs if your API returns an empty or null response body:
- If your Retrofit service returns a
Single<YourResponse>, but the API might send a null body, switch toMaybe<YourResponse>instead—Maybehandles empty/absent responses gracefully. - Add a null check in your Rx pipeline to catch where the null is creeping in:
yourApiService.fetchData() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext(response -> { if (response == null) { Log.e("NPE Debug", "Raw response is null!"); } else if (response.getResultsList() == null) { Log.e("NPE Debug", "Results list inside response is null!"); } }) .subscribe(...);
3. Log the Raw API Response
The fastest way to confirm if the API is sending unexpected nulls is to log the full raw response. Add an OkHttp interceptor to your Retrofit setup:
OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); // Use this client when building your Retrofit instance Retrofit retrofit = new Retrofit.Builder() .baseUrl("your_api_url") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build();
This will print the full JSON response in your logs, so you can see exactly which fields are null or missing.
4. Fragment Lifecycle & Context Checks
Since you're working in a Fragment, make sure you're not accessing null context or views when your Rx call completes:
- Avoid using
getActivity()without a null check—if the fragment is detached when the response comes in, this will throw an NPE. UserequireContext()only if you're certain the fragment is attached, or wrap context-dependent code:if (isAdded()) { // Safe to use getActivity()/requireContext() here resultsList.add(...); yourAdapter.notifyDataSetChanged(); } - Double-check that
resultsListis initialized before any async calls try to modify it. Your snippet shows you're initializing it inonCreateView, but if your Rx subscription fires before this method completes, you'll get an NPE when trying to add items.
If you can share more code (like your Retrofit service interface, full POJO class, and the complete Rx subscription logic), we can narrow this down even further. But these steps should help you track down the missing piece.
内容的提问来源于stack exchange,提问作者Bo Z

