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
- Make the creator always return a non-null header, e.g. (context, layout) -> new ClassicsHeader(context).
- If you do not want a default header, do not register a creator at all — remove the setDefaultRefreshHeaderCreator call.
- Audit every return path of a multi-branch creator and end it with a guaranteed fallback header.
- 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
- Treat DefaultRefreshHeaderCreator as non-nullable-by-contract: end every creator with an unconditional 'return new ClassicsHeader(context);' style fallback.
- Do not register a creator if you set headers per-layout in XML or code.
- Add ProGuard keep rules for header classes referenced inside creators.
- Cover creators with a unit test asserting non-null return on all branches.
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
- DefaultRefreshFooterCreator can not return null
- 最多只支持3个子View,Most only support three sub view
- Error in parsing ${pathData}
- error in parsing "${s}"
AI-assisted analysis of scwang90/SmartRefreshLayout@224db48f8a (2026-08-14).
Data as JSON: /api/errors/e2e724c0842aa6c9.
Report an issue: GitHub.