viromedia / viro

ViroReact: AR and VR using React Native
MIT License
2.31k stars 483 forks source link

Viro on Android crashes (GLSurfaceView) when using Drawer from react-navigation #620

Open tuur29 opened 5 years ago

tuur29 commented 5 years ago

Environment

Please provide the following information about your environment:

  1. Development OS: Mac, Windows
  2. Device OS & Version:
  3. Version: Viro 2.14.0, React Native 0.59.3
  4. Device(s):
    • Pixel 3 (non xl) on Android 9.0 (April sec update, PQ2A)
    • LG G6 (H870) on Andoid 8.0 (November sec update, V20g)
    • iPhone 7 with iOS 12.2

Description

My android app crashes when using the DrawerNavigator from react-navigation. This happens when you navigate back to the ViroScene. This is the error in the android logcat:

NullPointerException: Attempt to invoke virtual method 'android.view.SurfaceHolder
android.opengl.GLSurfaceView.getHolder()' on a null object reference at 
com.viro.core.ViroViewARCore$ViroARRenderer.onSurfaceCreated

Doesn't happen on iOS but happens on both Android 8 & 9 (check devices above).

388 issue seems related, but the 'solution' isn't helpful in the case of drawer navigation.

Possible workaround

We tried fixing this issue by manually destroying the ViroScene before navigation happens and only rendering it after navigation to the page has completed with NavigationEvents. This works, but obviously the coordinate system is reset and all objects have moved since we built a new ViroScene. Not a great solution.

Reproducible Demo

I made a small demo project. You can view the important code on my gist: https://gist.github.com/tuur29/ff0a17a6ced257b37977bc9e2b849187

The full project can be downloaded here: viro-nav.zip

  1. Download project and install node packages
  2. Set apikey in App.js
  3. run npm android or yarn android to build a android app
  4. Follow instructions on screen or description above

Video

ezgif-1-7f47447e99d3

shokimble commented 5 years ago

Interesting. I'm using the DrawerLayout from react-native-gesture-handler which react-navigation drawer is based upon.

I've not hit it with emulated devices or a Nokia 6.1 I have. Not tried other devices yet. Could be specific hardware that has the problem.

I was going to suggest disabling native animations but DrawerLayout uses them too.

antoinerousseau commented 5 years ago

I'm having this crash as well when used in react-navigation. My current workaround is to remove (unmount) the viro scene before leaving the nav screen, by waiting a few hundred milliseconds, but it's complicating my code and my UI...

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.SurfaceHolder android.opengl.GLSurfaceView.getHolder()' on a null object reference
    at com.viro.core.ViroViewARCore$ViroARRenderer.onSurfaceCreated(ViroViewARCore.java:262)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1539)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

related deps:

"react-native": "0.59",
"react-native-gesture-handler": "1.3",
"react-native-reanimated": "^1.2.0",
"react-native-screens": "1.0.0-alpha.22",
"react-navigation": "^3.12.1",
"react-viro": "^2.16.0",
radvani commented 5 years ago

This looks like a lifecycle issue caused by rapidly creating and disposing the view. We have a potential mitigation for this in the next release. Thanks!

antoinerousseau commented 5 years ago

This looks like a lifecycle issue caused by rapidly creating and disposing the view. We have a potential mitigation for this in the next release. Thanks!

Perfect, thank you very much!

antoinerousseau commented 5 years ago

@radvani the crash still happens with the freshly released ViroReact v2.17.0, although the release notes say "Fixed potential NPEs when using React Navigation drawer." đŸ˜¢

FATAL EXCEPTION: GLThread 3471
Process: com.artefac, PID: 28594
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.SurfaceHolder android.opengl.GLSurfaceView.getHolder()' on a null object reference
    at com.viro.core.ViroViewARCore$ViroARRenderer.onSurfaceChanged(ViroViewARCore.java:304)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1555)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
nhatvuminh commented 3 years ago

I have same issue with react-navigation/bottom-tabs. Any update or fix it?

nhatvuminh commented 3 years ago

Good news! I'm trying with createBottomTabNavigator and react-navigation. In TabNavigator, I'm set

unmountOnBlur: true

crash is gone. Hope this help! :)

SamiChab commented 3 years ago

This answer solved my problem https://github.com/ViroCommunity/viro/issues/25#issuecomment-862032093

ViktorVojtek commented 2 years ago

Hello, I've got into this issue recently.

In case somebody is still struggling with this kind of problem, here is my drop to the sea...

It turn's out, this was related to react-navigation's stack navigator when in use together with viro on android. In my case the issue was regarding to nested navigation structure of navigation.

Basically when I want to navigate between screens from different navigation for example by:

Going from 'Product' screen to AR 'screen'. (Product screen in drawer navigator, AR screen in ArStack of TabNavigator)

navigation.navigate(
      'ARStack',
      {screen: 'AR', params: {id: product?.id}},
);

App crashed on android.

I figure out when I dispatch CommonActions.reset object to navigation, when I need to navigate deeply in nested navigation, app would not crash..

navigation.dispatch(
      CommonActions.reset({
        index: 0,
        routes: [
          {
            name: 'ARStack',
            params: {
              screen: 'AR',
              params: {id: product.id},
            },
          },
        ],
      }),
    );

Hope this helps...

dwknippers commented 2 years ago

I've found that Viktor's solution works most consistently, and with the benefit of unmounting, thank you very much for sharing đŸ’–

Do note that it appears to still crash on very fast navigation <500ms repeatedly, but that issue seems more hardware related.

ViktorVojtek commented 1 year ago

The solution for this issue is eventuelly this one: https://github.com/ViroCommunity/viro/issues/138#issuecomment-1336503711

soluelue commented 1 year ago

Hello..

I'm not using a tab bar, but I have encountered a similar issue when changing screens.

When you change the navigation and then invoke Viro after capturing focus, the related issue gets resolved.

import {useIsFocused, useNavigation} from '@react-navigation/native';

export default () => {
  const isFocused = useIsFocused();

  import React, {useEffect} from 'react';

  const viroScreen=()=>{
     if(!isFocused) return ;
     return(<ViroARSceneNavigator style={{flex: 1}}
                                     initialScene={{scene: ArtModelScene}}
                                     ref={arNavigator}
                                     viroAppProps={viroAppProps}
                                     autofocus={false}/>) 

 }

}

Hope this helps

JBhrayn commented 7 months ago

Just had this issue, I'm using drawer and tabs. My AR is nested as follows (drawer)/(tabs)/ar. Whenever I run a simple hello world in AR, it works perfectly until I navigate back and use the AR again, then I get such error.