[BottomTabsCustomRow] Fix crash attaching custom row to non-AppCompat activities - #8337
Merged
Merged
Conversation
BottomTabsCustomRowAttacher is registered process-wide, so tryAttach() runs for every activity in the app. It called Activity.findViewById(), which on an AppCompat activity routes through AppCompatDelegateImpl and forces createSubDecor() -- that throws IllegalStateException unless the activity's theme derives from Theme.AppCompat. Any activity inheriting a non-AppCompat theme therefore crashed on creation. Resolve android.R.id.content through the decor view instead, which never engages AppCompatDelegate. Activity.findViewById() already delegates to getWindow().getDecorView().findViewById(), so behaviour is unchanged for activities that do have a compatible theme. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
yedidyak
approved these changes
Jul 30, 2026
yedidyak
enabled auto-merge (squash)
July 30, 2026 08:16
yedidyak
disabled auto-merge
July 30, 2026 08:16
yedidyak
added a commit
to Yoavpagir/react-native-navigation
that referenced
this pull request
Jul 30, 2026
…ties Resolves the overlap with wix#8337 (merged as a563e9d), which fixed the same Theme.AppCompat crash by resolving android.R.id.content through the decor view instead of Activity.findViewById(). Kept both layers: master's safe lookup (removes the AppCompatDelegate landmine) plus this branch's NavigationActivity guard (also stops the global layout observer and decor-tree walk from running on every activity in the process). Net change vs master is now just the guard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
BottomTabsCustomRowAttacheris registered as process-wideApplication.ActivityLifecycleCallbacks, sotryAttach()runs for every activity in the host app (fromonActivityCreated,onActivityStarted,onActivityResumed,registerOnceandrescan).tryAttach()resolved the overlay host withActivity.findViewById(android.R.id.content). On an AppCompat activity that call routes throughAppCompatDelegateImpl.findViewById(), which callsensureSubDecor()->createSubDecor().createSubDecor()validates the theme and throws:The exception escapes
onActivityCreated, soperformLaunchActivity()raises aRuntimeExceptionand Android force-finishes the activity. There is notry/catchon the path.Any activity in the process that inherits a theme which is not a
Theme.AppCompatdescendant therefore crashes on creation, even though it has nothing to do with bottom tabs. This is easy to hit with activities that declare noandroid:themeof their own and so inherit an application theme such asTheme.App.Startingfromandroidx.core:core-splashscreen.A concrete case: AppAuth's
net.openid.appauth.RedirectUriReceiverActivity(an invisible activity that receives the OAuth redirect and declares no theme). It is force-finished before it can hand the intent toAuthorizationManagementActivity, so the authorization code is dropped andauthorize()never resolves - breaking OAuth/OIDC sign-in entirely on Android.Solution
android.R.id.contentfrom the decor view (scanRoot.findViewById(...)) instead of via the activity.View.findViewById()never engagesAppCompatDelegate, so no sub-decor is created and no theme validation runs.activity.findViewById()fallback used to derivescanRoot: it carried the same hazard, and ifdecorViewis unavailable there is no hierarchy to scan or attach to.Behaviour is unchanged for activities with a compatible theme -
Activity.findViewById()already delegates togetWindow().getDecorView().findViewById(), so the resolved view is the same. On activities wheresetContentView()has not run yet, the lookup now returnsnulland falls back toscanRootrather than eagerly building the AppCompat sub-decor as a side effect; those activities have noBottomTabschildren yet, soforEachBottomTabsis a no-op and lateronActivityStarted/onActivityResumed/ layout-observer passes attach as before.Worth considering as a follow-up (not included here, to keep this fix minimal): skipping non-RNN-hosted activities outright, since
BottomTabscan only exist in an RNN activity, andensureLayoutObservercurrently installs a global layout listener on every activity in the process.Extra information (Jira ticket, design doc, Slack thread, etc..)
customrowpackage being introduced between engine-native33.39.63(noBottomTabsCustomRowAttacher, redirect works) and33.39.68(attacher present, redirect crashes); reproduced on an Android emulator (API 35) with a Wix admin dev build.