yuliskov/SmartTube · error · IllegalStateException

VideoGridFragment doesn't attached to the activity

Error message

VideoGridFragment doesn't attached to the activity

What it means

VideoGridFragment.onCreate immediately requires a host activity because the very next lines cast getActivity() to LeanbackActivity to obtain the BackgroundManager and read UI prefs. If the fragment is created without an attached activity, getActivity() is null and it throws IllegalStateException instead of NPE-ing on the cast.

Source

Thrown at smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/browse/video/VideoGridFragment.java:53

public class VideoGridFragment extends GridFragment implements VideoSection {
    private static final String TAG = VideoGridFragment.class.getSimpleName();
    private static final int RESTORE_MAX_SIZE = 10_000;
    private VideoGroupObjectAdapter mGridAdapter;
    private final List<VideoGroup> mPendingUpdates = new ArrayList<>();
    private UriBackgroundManager mBackgroundManager;
    private VideoGroupPresenter mMainPresenter;
    private VideoCardPresenter mCardPresenter;
    private int mSelectedItemIndex = -1;
    private Video mSelectedItem;
    private float mVideoGridScale;
    private final Runnable mRestoreTask = this::restorePosition;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getActivity() == null) {
            throw new IllegalStateException("VideoGridFragment doesn't attached to the activity");
        }

        mMainPresenter = getMainPresenter();
        mCardPresenter = isShorts() ? new ShortsCardPresenter() : new VideoCardPresenter();
        mBackgroundManager = ((LeanbackActivity) getActivity()).getBackgroundManager();
        mVideoGridScale = MainUIData.instance(getActivity()).getVideoGridScale();

        setupAdapter();
        setupEventListeners();
        applyPendingUpdates();

        if (getMainFragmentAdapter().getFragmentHost() != null) {
            getMainFragmentAdapter().getFragmentHost().notifyDataReady(getMainFragmentAdapter());
        }
    }

    protected VideoGroupPresenter getMainPresenter() {
        return BrowsePresenter.instance(getContext());

View on GitHub (pinned to 3de8d90593)

Solutions

  1. Only create VideoGridFragment through a FragmentManager transaction (or leanback's PageRow/main-frame navigation) from a live LeanbackActivity host.
  2. Never call lifecycle methods manually on the instance; let the FragmentManager drive them.
  3. In tests, use FragmentScenario with a LeanbackActivity-compatible host so getActivity() is non-null at onCreate.
  4. If triggering navigation from async callbacks, check that the host activity is alive (!isFinishing/isDestroyed) before switching sections.

Example fix

// before — fragment driven manually with no host
VideoGridFragment grid = new VideoGridFragment();
grid.onCreate(null); // getActivity() == null → IllegalStateException

// after — attach through the framework; host is guaranteed at onCreate
getSupportFragmentManager().beginTransaction()
        .replace(R.id.browse_frame, new VideoGridFragment())
        .commit();
Defensive patterns

Strategy: validation

Validate before calling

// only navigate while attached to a live host
if (isAdded() && getActivity() instanceof LeanbackActivity && !getActivity().isFinishing()) {
    getFragmentManager().beginTransaction()
            .replace(R.id.browse_frame, new VideoGridFragment())
            .commit();
}

Prevention

When it happens

Trigger: Instantiating VideoGridFragment outside a FragmentManager transaction with a live host: manual new VideoGridFragment() followed by direct lifecycle calls, a detached/retained instance being re-created, or a fragment factory producing it before attachment.

Common situations: State restoration edge cases where the fragment is re-created during host teardown; tests instantiating the fragment directly with no host activity; code paths triggering grid creation from background callbacks after the activity is destroyed.

Related errors


AI-assisted analysis of yuliskov/SmartTube@3de8d90593 (2026-08-22). Data as JSON: /api/errors/8d6875e3681e6a0b. Report an issue: GitHub.