Blankj/AndroidUtilCode · error · NullPointerException

ContentView is null.

Error message

ContentView is null.

What it means

BaseFragment.findViewById throws a NullPointerException when the fragment's content view (mContentView) is null. mContentView is only assigned inside setContentView(), and only when bindLayout() returns a value greater than 0. The library throws hard because findViewById has no meaningful result without an inflated root view.

Source

Thrown at lib/base/src/main/java/com/blankj/base/BaseFragment.java:164

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        log("onSaveInstanceState");
        super.onSaveInstanceState(outState);
        outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
    }

    @Override
    public void onDestroy() {
        log("onDestroy");
        super.onDestroy();
    }

    public void applyDebouncingClickListener(View... views) {
        ClickUtils.applyGlobalDebouncing(views, mClickListener);
    }

    public <T extends View> T findViewById(@IdRes int id) {
        if (mContentView == null) throw new NullPointerException("ContentView is null.");
        return mContentView.findViewById(id);
    }

    protected void log(String msg) {
        if (isDebug == null) {
            isDebug = AppUtils.isAppDebug();
        }
        if (isDebug) {
            Log.d("BaseFragment", getClass().getSimpleName() + ": " + msg);
        }
    }
}

View on GitHub (pinned to 7b4caf9e54)

Solutions

  1. Move any findViewById / view-binding calls out of onCreate and onAttach into initView(savedInstanceState, mContentView) or onViewCreated, where mContentView is guaranteed set.
  2. Ensure your BaseFragment subclass overrides bindLayout() to return a valid @LayoutRes id (> 0) whenever you intend to call findViewById.
  3. If the fragment can legitimately have no layout (bindLayout()==0), guard each call with a null check on mContentView or on getView() before resolving views.
  4. After onDestroyView, null out your view references and stop calling findViewById to avoid acting on a stale/destroyed fragment.

Example fix

// before
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView tv = findViewById(R.id.tv); // crashes: mContentView still null
}

// after
@Override
public void initView(Bundle savedInstanceState, View contentView) {
    TextView tv = contentView.findViewById(R.id.tv); // safe: contentView is mContentView
}
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the root view, not findViewById, and only after it is set.
View root = getView(); // or mContentView if accessible
if (root != null) {
    TextView tv = root.findViewById(R.id.tv);
}

Type guard

// Fragment view-readiness guard
private boolean isViewReady(BaseFragment f) {
    return f.getView() != null;
}

Prevention

When it happens

Trigger: Calling findViewById(id) before onCreateView/onCreateView has run (e.g., from onCreate, onAttach, or a constructor), or in a BaseFragment subclass whose bindLayout() returns 0 (so setContentView() early-returns and never assigns mContentView).

Common situations: Initialising views or wiring listeners in onCreate instead of initView/onViewCreated; overriding bindLayout() to return 0 for a headless/empty fragment then still calling findViewById; calling findViewById from a background thread or a callback that fires after onDestroyView nulls the view.

Related errors


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/29e2611a5bdcd305. Report an issue: GitHub.