{"record":{"id":"893ed8f69d9cc28d","repo":"gyf-dev/ImmersionBar","slug":"fragment-must-be-attached-to-an-activity","errorCode":null,"errorMessage":"Fragment must be attached to an Activity.","messagePattern":"Fragment must be attached to an Activity\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"immersionbar/src/main/java/com/gyf/immersionbar/ImmersionBar.java","lineNumber":3069,"sourceCode":"     *\n     * @param activity the activity\n     */\n    ImmersionBar(Activity activity) {\n        mActivity = activity;\n        initCommonParameter(mActivity.getWindow());\n    }\n\n    /**\n     * 在Fragment里初始化\n     * Instantiates a new Immersion bar.\n     *\n     * @param fragment the fragment\n     */\n    ImmersionBar(Fragment fragment) {\n        mIsFragment = true;\n        Activity activity = fragment.getActivity();\n        if (activity == null) {\n            throw new IllegalArgumentException(\"Fragment must be attached to an Activity.\");\n        }\n        mActivity = activity;\n        mSupportFragment = fragment;\n        checkInitWithActivity();\n        initCommonParameter(mActivity.getWindow());\n    }\n\n    /**\n     * 在Fragment里初始化\n     * Instantiates a new Immersion bar.\n     *\n     * @param fragment the fragment\n     */\n    ImmersionBar(android.app.Fragment fragment) {\n        mIsFragment = true;\n        mActivity = fragment.getActivity();\n        mFragment = fragment;\n        checkInitWithActivity();","sourceCodeStart":3051,"sourceCodeEnd":3087,"githubUrl":"https://github.com/gyf-dev/ImmersionBar/blob/8cac10cd83d809eac54f42b37f92340c4a25c4ac/immersionbar/src/main/java/com/gyf/immersionbar/ImmersionBar.java#L3051-L3087","documentation":"The package-private ImmersionBar(Fragment) constructor calls fragment.getActivity() and requires a live Activity reference, because ImmersionBar ultimately applies insets to the Activity's Window. If getActivity() returns null the fragment is not attached, and the constructor throws IllegalArgumentException.","triggerScenarios":"Calling ImmersionBar.with(fragment) inside Fragment constructor, onCreate before onAttach completes (or after onDetach), or from a fragment whose host Activity is being destroyed.","commonSituations":"Initializing the bar in a field initializer; calling init() from an async callback that returns after detach; using the fragment in a detached state (e.g. retained fragment, notification-triggered work).","solutions":["Call ImmersionBar.with(fragment).init() only after the fragment is attached (onViewCreated or later)","Guard with fragment.isAdded() / fragment.getActivity() != null before using ImmersionBar","Cancel pending bar setup in onDetach and re-apply in onResume"],"exampleFix":"// before\npublic void onCreate(Bundle s) { ImmersionBar.with(this).init(); } // may throw\n// after\n@Override\npublic void onViewCreated(View v, Bundle s) {\n    if (isAdded()) {\n        ImmersionBar.with(this).statusBarDarkFont(true).init();\n    }\n}","handlingStrategy":"validation","validationCode":"if (fragment.isAdded() && fragment.getActivity() != null) { ImmersionBar.with(fragment).init(); }","typeGuard":"boolean fragmentReady(Fragment f) { return f != null && f.isAdded() && f.getActivity() != null; }","tryCatchPattern":"try { ImmersionBar.with(fragment).init(); } catch (IllegalArgumentException e) { Log.w(TAG, \"Fragment not attached, skipping bar init\"); }","preventionTips":["Call ImmersionBar.with(fragment) in onViewCreated or later","Guard with isAdded() in async callbacks","Re-apply bar config in onResume after detach"],"tags":["android","fragment","lifecycle","argument-validation"],"backgroundTag":"invalid-state-transition","analyzedSha":"8cac10cd83d809eac54f42b37f92340c4a25c4ac","analyzedAt":"2026-09-08T11:52:01.757Z","contentChangedAt":"2026-09-08T11:52:01.757Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}