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

Android ViewPager+Fragment Volley空对象引用错误及优化方案咨询

Hey there, let's break down your problem step by step and figure out the best fixes!

1. Why the NullPointerException Occurs

The crash happens because when you switch ViewPager pages beyond the setOffscreenPageLimit value, the unused Fragments get detached from the Activity (their getActivity() returns null). If a Volley network request finishes after the Fragment is detached, calling getActivity().getApplicationContext() in the onResponse callback will throw a null pointer—since there's no longer an Activity attached to the Fragment.

2. Fix the NullPointerException

Here are two robust solutions to avoid this issue without forcing all Fragments to stay in memory:

Option 1: Check Fragment Attachment Before Using Context

Add a check to ensure the Fragment is still attached to an Activity before accessing any context-related methods in your Volley callbacks:

@Override
public void onResponse(JSONObject response) {
    // Exit early if Fragment is no longer attached to Activity
    if (!isAdded()) {
        return;
    }
    
    LastWolrdNewsParser parser = new LastWolrdNewsParser();
    ArrayList<LastWorldNews> news = parser.ParseJson(response);
    // Use getContext() instead of getActivity().getApplicationContext() for safer context access
    LastWorldNewsAdapter adapter = new LastWorldNewsAdapter(getContext(), 
                                 R.layout.last_world_news_list_item, news);
    
    pb.setVisibility(View.GONE);
    if (mListView.getVisibility() == View.INVISIBLE || mListView.getVisibility() == View.GONE){
        mListView.setVisibility(View.VISIBLE);
    }
    mListView.setAdapter(adapter);
}

Do the same check in your error callback:

@Override
public void onErrorResponse(VolleyError error) {
    if (!isAdded()) {
        return;
    }
    pb.setVisibility(View.GONE);
}

getContext() is a better choice here than getActivity().getApplicationContext() because it's tied to the Fragment's lifecycle and won't cause issues if the Fragment is properly attached.

Option 2: Use ViewModel to Manage Data

For a more scalable fix, move your network request and data storage logic to a ViewModel. ViewModels survive Fragment lifecycle changes (like detaching/reattaching from the Activity), so even if the Fragment is destroyed, the request can complete and the data will be retained. When the Fragment is recreated, it can fetch the cached data from the ViewModel instead of making a new request.

3. About setOffscreenPageLimit

Setting setOffscreenPageLimit to 6 will keep all 7 Fragments in memory, which avoids the crash but is not ideal—it will significantly increase your app's memory usage, especially if each Fragment loads large list data. The solutions above are far better because they let the system manage memory efficiently while preventing the null pointer.

4. Is Canceling Volley Requests in onPause/onDestroy Standard?

Your approach is correct, but there's a small bug to fix first:

  • Your request variable is local to the prepareData() method, so it's not accessible in onPause or onDestroy. You need to declare it as a member variable of the Fragment:
private JsonObjectRequest request; // Declare as Fragment member

private void prepareData() {
    request = new JsonObjectRequest(Request.Method.GET, url, null, ...);
    RequestQueue quew = Volley.newRequestQueue(getContext());
    quew.add(request);
}

Canceling requests in onPause is smart because it stops unnecessary network activity when the Fragment is not visible. Double-checking in onDestroy adds an extra layer of protection against memory leaks, even though Volley's RequestQueue will automatically clean up requests when the Activity is destroyed.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:18:28