scwang90/SmartRefreshLayout · error · RuntimeException

DefaultRefreshHeaderCreator can not return null

Error message

DefaultRefreshHeaderCreator can not return null

What it means

In onAttachedToWindow(), if no header was set from XML or code (mRefreshHeader == null) and a global default header creator is registered via SmartRefreshLayout.setDefaultRefreshHeaderCreator(...), that creator returned null — which the library treats as a programming error and throws. The creator contract requires a non-null RefreshHeader; the @noinspection ConstantConditions comment shows the authors deliberately made this a hard failure.

Source

Thrown at refresh-layout-kernel/src/main/java/com/scwang/smart/refresh/layout/SmartRefreshLayout.java:412

     * 2.做 Content 为空时的 TextView 提示
     * 3.智能开启 嵌套滚动 NestedScrollingEnabled
     * 4.初始化 主题颜色 和 调整 Header Footer Content 的显示顺序
     */
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mAttachedToWindow = true;

        final View thisView = this;
        // 在非编辑模式下,如果 onFinishInflate 初始化组件未成功,onAttachedToWindow 可以进行补充处理
        if (!thisView.isInEditMode()) {

            if (mRefreshHeader == null) {
                if (sHeaderCreator != null) {
                    RefreshHeader header = sHeaderCreator.createRefreshHeader(thisView.getContext(), this);
                    //noinspection ConstantConditions
                    if (header == null) {
                        throw new RuntimeException("DefaultRefreshHeaderCreator can not return null");
                    }
                    setRefreshHeader(header);
                }
            }
            if (mRefreshFooter == null) {
                if (sFooterCreator != null) {
                    RefreshFooter footer = sFooterCreator.createRefreshFooter(thisView.getContext(), this);
                    //noinspection ConstantConditions
                    if (footer == null) {
                        throw new RuntimeException("DefaultRefreshFooterCreator can not return null");
                    }
                    setRefreshFooter(footer);
                }
            } else {
                mEnableLoadMore = mEnableLoadMore || !mManualLoadMore;
            }

            if (mRefreshContent == null) {

View on GitHub (pinned to 224db48f8a)

Solutions

  1. Make the creator always return a non-null header, e.g. (context, layout) -> new ClassicsHeader(context).
  2. If you do not want a default header, do not register a creator at all — remove the setDefaultRefreshHeaderCreator call.
  3. Audit every return path of a multi-branch creator and end it with a guaranteed fallback header.
  4. If a header class seems missing at runtime, check ProGuard/R8 keep rules for the header class used inside the creator.

Example fix

// before
SmartRefreshLayout.setDefaultRefreshHeaderCreator((context, layout) -> {
    if (useMaterial) return new MaterialHeader(context);
    return null; // crashes on attach
});

// after
SmartRefreshLayout.setDefaultRefreshHeaderCreator((context, layout) -> {
    if (useMaterial) return new MaterialHeader(context);
    return new ClassicsHeader(context);
});
Defensive patterns

Strategy: validation

Validate before calling

// Exercise the creator once at startup so a null return fails loudly in your code, not at attach time
DefaultRefreshHeaderCreator creator = (context, layout) -> buildHeader(context);
RefreshHeader probe = creator.createRefreshHeader(context, null);
if (probe == null) throw new IllegalStateException("Header creator must never return null");
SmartRefreshLayout.setDefaultRefreshHeaderCreator(creator);

Prevention

When it happens

Trigger: Registering sHeaderCreator with SmartRefreshLayout.setDefaultRefreshHeaderCreator((context, layout) -> null) — or a lambda whose body can return null on some branch (e.g. conditional instantiation that falls through) — and then attaching any SmartRefreshLayout to the window without an explicit header.

Common situations: Copy-pasting a creator stub that has no return yet; a creator that returns null conditionally (theme/AB test branch) and one branch was missed; migration to a different header class where the constructor was removed but the return statement still returns null; proguard/R8 stripping a header class so reflection-based creation yields null.

Related errors


AI-assisted analysis of scwang90/SmartRefreshLayout@224db48f8a (2026-08-14). Data as JSON: /api/errors/e2e724c0842aa6c9. Report an issue: GitHub.