react-native-screens: [Android] Crash: no view found for id 0x1f1 (unknown) for fragment ScreenFragment

Today, I attempted to update to the latest react-navigation, and I figured I would try to use react-native-screens to improve performance. Unfortunately, it crashes on Android immediately upon opening. I have followed all of the instalation instructions, and I can confirm that my code works fine if I a) do not call useScreens() and b) extend from ReactActivity instead in the code below.

The exception only shows up in adb logcat:

49:04.038 11335 11335 E AndroidRuntime: FATAL EXCEPTION: main
12-22 17:49:04.038 11335 11335 E AndroidRuntime: Process: com.zonderstudios.zonder, PID: 11335
12-22 17:49:04.038 11335 11335 E AndroidRuntime: java.lang.IllegalArgumentException: No view found for id 0x1f1 (unknown) for fragment ScreenFragment{c8216f5 #0 id=0x1f1}
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2617)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2388)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2344)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:790)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:99)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:164)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:6494)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
12-22 17:49:04.038 11335 11335 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
12-22 17:49:04.040  1634  1644 W ActivityManager:   Force finishing activity com.zonderstudios.zonder/.MainActivity
12-22 17:49:04.047  1634  1649 I ActivityManager: Showing crash dialog for package com.zonderstudios.zonder u0

Here is my MainActivity.java.

package com.zonderstudios.zonder;
import android.os.Bundle;
import com.facebook.react.ReactFragmentActivity;
import org.devio.rn.splashscreen.SplashScreen;
import android.content.Intent;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

public class MainActivity extends ReactFragmentActivity {

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "zonder";
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        MainApplication.getCallbackManager().onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this, false);
        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        // I also tried this, along with deleting the two lines for splash screen and set theme:
        // super.onCreate(null);
    }

    @Override
    protected void onPause() {
        SplashScreen.hide(this);
        super.onPause();
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Override
            protected ReactRootView createRootView() {
                    return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }
        };
    }
}

Any thoughts on fixing this? My one thought might be that there is a conflict with something else. Not sure, though.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 13
  • Comments: 41 (2 by maintainers)

Commits related to this issue

Most upvoted comments

This issue is happening because this library is not using Fragments correctly.

The issue happens when a ScreenContainer is unmounted. When this happens it tries to disconnect all the Screen instances here, which calls into here.

However, it appears the expectation in android is that these sort of operations should be handled through the FragmentManager which will clear a bunch of private instance variables, most importantly this one.

If the ScreenContainer is removed from the view hierarchy and that id is not cleared, then the next time the FragmentManager tries to do something with that Fragment it will attempt to find the container in the view hierarchy, which will fail and cause the above exception.

Here’s a minimal reproduction:

import React, { PureComponent } from 'react'
import { View } from 'react-native'
import { useScreens } from 'react-native-screens'
import {
  createSwitchNavigator, createStackNavigator, createAppContainer
} from 'react-navigation'

useScreens()

function SomeLoginScreen() {
  return <View style={{ backgroundColor: 'blue', flex: 1 }} />
}

function SomeAppScreen() {
  return <View style={{ backgroundColor: 'red', flex: 1 }} />
}

const LoginStack = createStackNavigator({
  Form: SomeLoginScreen
})

const AppStack = createStackNavigator({
  Home: SomeAppScreen
})


const Navigator = createSwitchNavigator({
  Login: LoginStack,
  App: AppStack
})

class App extends PureComponent {
  static router = Navigator.router

  componentDidMount() {
    // Crash:
    this.props.navigation.navigate({ routeName: "App" })

    // Does not crash
    // setTimeout(() => this.props.navigation.navigate({ routeName: "App" }), 0)
  }


  render() {
    return  <Navigator {...this.props} />
  }
}

export default createAppContainer(App)

I suspect that there may be multiple ways of triggering this crash, but the code above seems to cover the Switch navigator case specifically.

@kmagiera are there any estimations on fixing this?

Hi @kmagiera, I’ve managed to create repro https://github.com/dominiczaq/react-native-screens-no-view-found-issue

The issue is occurring when component renders <Stack.Navigator> and while navigating the render changes to null.

It seems that there are no issues when Stacks are changing rapidly, only when the Stacks are unmounted while navigating.

1.0.0-alpha.22 does not to fix this. It is happening extremely consistently even at that version.

I’ve been doing a bit of digging on this issue. Still haven’t found a solution, but I did make some observations.

@kmagiera Could you take a look at some of the observations below to see if you have any ideas?

  1. This happens because something is trying to find a ScreenContainer that does not exist in the view hierarchy.

  2. The switch navigator does not use react-native-screens at all. It renders a SceneView which is just a context wrapper which passes the screenProps and navigation props.

  3. Rendering a stack navigator inside a switch navigator seems to cause this very consistently.

  4. I noticed that my there were two separate instances of ScreenContainer created, but the View hierarchy from the exception log only includes one instance of that component.

  5. It initializes a few Screen instances before creating the second instance of ScreenContainer. Perhaps one of those screens is getting attached to some sort of orphaned container?

I’m wiped for today, but I’m going to continue looking into this tomorrow, so if anyone has any more data or observations to share I’d appreciate it.

Unfortunately, after moving useScreens() to our root component’s componentDidMount(), we’re still seeing this error:

java.lang.IllegalArgumentException No view found for id 0xbf3 (unknown) for fragment ScreenFragment{9f211c8 #10 id=0xbf3} 
    FragmentManager.java:1413 android.support.v4.app.FragmentManagerImpl.moveToState
    FragmentManager.java:2601 android.support.v4.app.FragmentManagerImpl.addAddedFragments
    FragmentManager.java:2372 android.support.v4.app.FragmentManagerImpl.executeOpsTogether
    FragmentManager.java:2328 android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute
    FragmentManager.java:2229 android.support.v4.app.FragmentManagerImpl.execPendingActions
    FragmentManager.java:700 android.support.v4.app.FragmentManagerImpl$1.run
    Handler.java:739 android.os.Handler.handleCallback
    Handler.java:95 android.os.Handler.dispatchMessage
    Looper.java:145 android.os.Looper.loop
    ActivityThread.java:6219 android.app.ActivityThread.main
    Method.java:-2 java.lang.reflect.Method.invoke
    Method.java:372 java.lang.reflect.Method.invoke
    ZygoteInit.java:1399 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
    ZygoteInit.java:1194 com.android.internal.os.ZygoteInit.main

Any other possible workaround? Thanks!

Hi @WoLewicki I’m still seeing this crash on the app making use of "react-native-screens": "^2.4.0",. I’ve created a new issue in #463

Yes, the fix works. I believe this issue could be closed.

I have a very ugly workaround that uses reflection, but it’s enough to get running.

You can see it here.

Note: That branch should not be used as is without careful consideration. There’s a few changes in there specific to the environment we’re using, so please only consider it as reference.

Note 2: If using this hack with proguard, make sure you don’t mangle Fragment.

It would be great if we could get this fixed, because as far as I can tell you can’t use the react navigation switch navigator without it. This makes it hard to implement our auth flow. We’ve been forced to disable react-native-screens on android.

I’m having the same issue. I couldn’t be sure it was an issue with this lib, but I tried removing it and the crash stopped.

Does anyone have an idea where to start looking to solve this?

This happens to me everytime i use react-navigation with some rehydrated state (redux-persist) and try to navigate into another stack in a switch navigator as soon as the app starts (ex: user already logged). I will try to make up some repro to make this problem more clear… But i get the same error in android studio and just by removing useScreens() everything comes back to normal.

Hi @henrymoulton The issue was resolved by adding the following code in App.js: import { enableFreeze, enableScreens } from ‘react-native-screens’; enableFreeze(true); enableScreens(false); This code snippet utilizes react-native-screens to enable freeze optimization and disable screens. It helped resolve a navigation-related problem, likely improving performance and stability in the app’s navigation flow.

@dominiczaq do you know if the merged changes fix the bug?