{"record":{"id":"e48b1d7e9057d01d","repo":"yuliskov/SmartTube","slug":"can-t-create-playbackfragment-the-context-is-null","errorCode":null,"errorMessage":"Can't create PlaybackFragment: the context is null","messagePattern":"Can't create PlaybackFragment: the context is null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/PlaybackFragment.java","lineNumber":134,"sourceCode":"    private DebugInfoManager mDebugInfoManager;\n    private UriBackgroundManager mBackgroundManager;\n    private RowsSupportFragment mRowsSupportFragment;\n    private boolean mIsUIAnimationsEnabled = false;\n    private boolean mIsEngineBlocked;\n    private MediaSessionCompat mMediaSession;\n    private MediaSessionConnector mMediaSessionConnector;\n    private DoubleTapPlayerAdapter mDoubleTapPlayerAdapter;\n    private YouTubeOverlay mYouTubeOverlay;\n    private Boolean mIsControlsShownPreviously;\n    private Video mPendingFocus;\n    private String mSelectedVideoId;\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(null); // trying to fix bug with presets\n\n        if (getContext() == null) {\n            throw new IllegalStateException(\"Can't create PlaybackFragment: the context is null\");\n        }\n\n        mSelectedVideoId = savedInstanceState != null ? savedInstanceState.getString(SELECTED_VIDEO_ID, null) : null;\n        mVideoGroupAdapters = new HashMap<>();\n        mBackgroundManager = getLeanbackActivity().getBackgroundManager();\n        mBackgroundManager.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.player_background));\n        mPlayerInitializer = new ExoPlayerInitializer(getContext());\n\n        mPlaybackPresenter = PlaybackPresenter.instance(getContext());\n        mPlaybackPresenter.setView(this);\n        mExoPlayerController = new ExoPlayerController(getContext(), mPlaybackPresenter);\n\n        // Fix open previous video\n        if (mPlaybackPresenter.getVideo() != null) {\n            mSelectedVideoId = null;\n        }\n\n        initPresenters();","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/yuliskov/SmartTube/blob/3de8d90593e0166f012ca18cc3c7ba45bfd68ac4/smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/PlaybackFragment.java#L116-L152","documentation":"PlaybackFragment.onCreate checks getContext() before doing anything else, because every following line needs a Context (BackgroundManager from the host LeanbackActivity, ExoPlayerInitializer, PlaybackPresenter). A null context at onCreate means the fragment has no attached host, so it throws IllegalStateException to fail fast with a clear message instead of an NPU later. Note super.onCreate(null) is passed deliberately (preset-restore workaround), so the null check is the fragment's own guard.","triggerScenarios":"PlaybackFragment instantiated or restored without a host: manual construction with direct lifecycle calls, restore after the activity was destroyed, or navigation triggered from a detached/async callback where the host is gone by the time onCreate runs.","commonSituations":"Process-death or configuration-change restore races; deep-link handling that shows playback after the activity finished; background events (e.g., player notifications, auto-play timers) starting playback onto a dead host; unit tests creating the fragment directly.","solutions":["Open PlaybackFragment only through FragmentManager/leanback playback transactions from a live host activity.","Before starting playback from async callbacks, verify the host exists and is not finishing/destroyed (isAdded(), !requireActivity().isFinishing()).","Cancel pending navigation (handlers/rx subscriptions) when the host is destroyed, or guard them with isAdded().","In tests, host the fragment with FragmentScenario attached to a real LeanbackActivity-derived activity."],"exampleFix":"// before — navigation from a detached async callback\nmHandler.postDelayed(() -> showPlaybackFragment(video), 5000);\n// activity may be gone when this fires → getContext() == null at onCreate\n\n// after — guard with attach state\nmHandler.postDelayed(() -> {\n    if (isAdded() && !requireActivity().isFinishing()) {\n        showPlaybackFragment(video);\n    }\n}, 5000);","handlingStrategy":"validation","validationCode":"// before starting playback from any async path\nif (isAdded() && getContext() != null && !requireActivity().isFinishing()) {\n    startPlaybackFragment(video);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Open PlaybackFragment only via FragmentManager transactions on a live host.","Cancel/de-register pending navigation when the host is destroyed.","Guard every delayed navigation callback with isAdded()."],"tags":["android","android-tv","fragment","lifecycle","playback"],"backgroundTag":"fragment-not-attached","analyzedSha":"3de8d90593e0166f012ca18cc3c7ba45bfd68ac4","analyzedAt":"2026-08-22T09:19:26.383Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}