{"record":{"id":"00879acc1a8b35b8","repo":"scwang90/SmartRefreshLayout","slug":"defaultrefreshfootercreator-can-not-return-null","errorCode":null,"errorMessage":"DefaultRefreshFooterCreator can not return null","messagePattern":"DefaultRefreshFooterCreator can not return null","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"refresh-layout-kernel/src/main/java/com/scwang/smart/refresh/layout/SmartRefreshLayout.java","lineNumber":422,"sourceCode":"        // 在非编辑模式下，如果 onFinishInflate 初始化组件未成功，onAttachedToWindow 可以进行补充处理\n        if (!thisView.isInEditMode()) {\n\n            if (mRefreshHeader == null) {\n                if (sHeaderCreator != null) {\n                    RefreshHeader header = sHeaderCreator.createRefreshHeader(thisView.getContext(), this);\n                    //noinspection ConstantConditions\n                    if (header == null) {\n                        throw new RuntimeException(\"DefaultRefreshHeaderCreator can not return null\");\n                    }\n                    setRefreshHeader(header);\n                }\n            }\n            if (mRefreshFooter == null) {\n                if (sFooterCreator != null) {\n                    RefreshFooter footer = sFooterCreator.createRefreshFooter(thisView.getContext(), this);\n                    //noinspection ConstantConditions\n                    if (footer == null) {\n                        throw new RuntimeException(\"DefaultRefreshFooterCreator can not return null\");\n                    }\n                    setRefreshFooter(footer);\n                }\n            } else {\n                mEnableLoadMore = mEnableLoadMore || !mManualLoadMore;\n            }\n\n            if (mRefreshContent == null) {\n                for (int i = 0, len = getChildCount(); i < len; i++) {\n                    View view = getChildAt(i);\n                    if ((mRefreshHeader == null || view != mRefreshHeader.getView()) &&\n                            (mRefreshFooter == null || view != mRefreshFooter.getView())) {\n                        mRefreshContent = new RefreshContentWrapper(view);\n                    }\n                }\n            }\n            if (mRefreshContent == null) {\n                final int padding = SmartUtil.dp2px(20);","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/scwang90/SmartRefreshLayout/blob/224db48f8af897a930b810a6b6fc55af8cef0d57/refresh-layout-kernel/src/main/java/com/scwang/smart/refresh/layout/SmartRefreshLayout.java#L404-L440","documentation":"The footer counterpart of the header error: in onAttachedToWindow(), when no footer was configured (mRefreshFooter == null) and a global default footer creator is registered via SmartRefreshLayout.setDefaultRefreshFooterCreator(...), that creator returned null and the library throws immediately. The creator must return a non-null RefreshFooter; returning null violates the API contract.","triggerScenarios":"Registering sFooterCreator with setDefaultRefreshFooterCreator((context, layout) -> null), or a lambda whose conditional branches can fall through to a null return, then attaching any SmartRefreshLayout without an xml/code-set footer. Fires only on the footer path — header path is handled by the sibling check above it.","commonSituations":"Disabling load-more by returning null from the footer creator (wrong approach — use setEnableLoadMore(false) instead); unfinished creator stubs during prototyping; branch logic where one theme returns a footer and another returns null; version upgrades where a footer class moved packages and the old import resolves to something uninstantiable.","solutions":["If the intent was to disable load-more, call refreshLayout.setEnableLoadMore(false) instead of returning null from the creator.","Otherwise make the creator always return a non-null footer, e.g. (context, layout) -> new ClassicsFooter(context).","If no global default footer is wanted, remove the setDefaultRefreshFooterCreator registration entirely.","Audit all return branches of a conditional creator and add a guaranteed non-null fallback."],"exampleFix":"// before (crashes on attach)\nSmartRefreshLayout.setDefaultRefreshFooterCreator((context, layout) -> null); // tried to disable load-more\n\n// after\nrefreshLayout.setEnableLoadMore(false); // correct way to disable load-more\n// or, if you want a default footer:\nSmartRefreshLayout.setDefaultRefreshFooterCreator((context, layout) -> new ClassicsFooter(context));","handlingStrategy":"validation","validationCode":"// Probe the creator once before registering so null returns surface immediately\nDefaultRefreshFooterCreator creator = (context, layout) -> buildFooter(context);\nif (creator.createRefreshFooter(context, null) == null) {\n    throw new IllegalStateException(\"Footer creator must never return null\");\n}\nSmartRefreshLayout.setDefaultRefreshFooterCreator(creator);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never return null from a footer creator to 'disable' load-more — call setEnableLoadMore(false) instead.","End conditional creators with an unconditional non-null fallback footer (e.g. ClassicsFooter).","Do not register a default footer creator when each layout declares its own footer.","Unit-test all creator branches for non-null returns."],"tags":["android","smartrefreshlayout","null-return","callback-contract","load-more"],"backgroundTag":null,"analyzedSha":"224db48f8af897a930b810a6b6fc55af8cef0d57","analyzedAt":"2026-08-14T10:09:28.455Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}