React Native 栈溢出异常

6
我在安卓上的React Native应用中遇到了以下异常。
E/unknown:ReactNative: Exception in native call
    com.facebook.react.uimanager.IllegalViewOperationException: StackOverflowException
        at com.facebook.react.ReactRootView.handleException(ReactRootView.java:563)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:669)
        at android.view.View.draw(View.java:14468)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.draw(View.java:14468)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.getDisplayList(View.java:13357)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.getDisplayList(View.java:13357)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.getDisplayList(View.java:13357)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at android.view.View.draw(View.java:14468)
        at android.widget.FrameLayout.draw(FrameLayout.java:472)
        at android.widget.ScrollView.draw(ScrollView.java:1603)
        at com.facebook.react.views.scroll.ReactScrollView.draw(ReactScrollView.java:354)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.draw(View.java:14468)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:663)
        at android.view.View.draw(View.java:14468)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at android.view.View.getDisplayList(View.java:13357)
        at android.view.View.getDisplayList(View.java:13404)
        at android.view.View.draw(View.java:14182)
        at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
        at android.view.View.draw(View.java:14468)
        at android.widget.FrameLayout.draw(FrameLayout.java:472)
        at android.widget.HorizontalScrollView.draw(HorizontalScrollView.java:1609)
        at com.facebook.react.views.scroll.ReactHorizontalScrollView.draw(ReactHorizontalScrollView.java:275)
        at android.view.View.getDisplayList(View.java:13362)
        at android.view.View.getDisplayList(View.java:13404)
        at android.v

我的React-Native应用程序中有以下版本:

  • react-native: 0.55.3
  • react: 16.3.1
  • Android: 4.4.2

主要问题是,这个异常并没有特定的情况,它可能发生在应用程序的任何地方。例如,在您一直使用应用程序一段时间后,尝试转到某个屏幕时,它会崩溃并显示此异常。

我已经搜索了很多关于IllegalViewOperationException的内容。

https://github.com/facebook/react-native/issues/13984 -> 这里的问题建议删除LayoutAnimation,但是我已经完全从项目中删除它,但仍然面临该问题。

com.facebook.react.uimanager.IllegalViewOperationException: Trying to add unknown view tag -> 这里的异常似乎是由另一个原因引起的,而在我的情况下,我没有未知的视图标记问题。

我已经搜索了很多关于react-native中的StackOverflowException,但即使在它的GitHub问题中,也没有任何结果。

我也检查了Exception in native call错误。例如,在此链接中,E/unknown:React: Exception in native call,该问题是由打包引起的。但我的情况与打包无关。我可以在模拟器中成功运行应用程序并在屏幕之间导航。该异常也会在真实设备上的发布模式下发生。

我找不到包含Exception in native callIllegalViewOperationExceptionStackOverflowException关键字的答案。这种异常仅发生在Android 4.x版本的设备上。它不会在Android 5及更高版本上发生。我猜它可能与设备的内存不足有关,或者设备可能无法处理连续页面导航中的太多渲染。您有任何关于如何防止这种异常的想法吗?


我也正好遇到了这个问题,你的问题解决了吗? - Samira kalantari
1
我也遇到了IllegalViewOperationException堆栈溢出问题。我检查了我的adb logcat日志,找到了这个相关行。“在调用Landroid/text/SpanSet时发生堆栈溢出”。 - Ashoat
你好,你解决了这个问题吗? - Artur Eshenbrener
Stackoverflowexception 表示堆栈已满 - 太多的函数调用可能会消耗堆栈。检查调用图并查看是否有某个函数被调用了太多次。 - kiner_shah
1个回答

0

很可能你有一个递归操作强制重新渲染。

https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java

  @Override
  protected void dispatchDraw(Canvas canvas) {
    try {
      super.dispatchDraw(canvas);
    } catch (StackOverflowError e) {
      // Adding special exception management for StackOverflowError for logging purposes.
      // This will be removed in the future.
      handleException(e);
    }
  }

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java

dispatchDraw方法是Android SDK的一部分。它是视图系统的一部分,允许在ViewGroup(根组件)内绘制其他视图。由于这个过程的本质(因为ViewGroup也是一个View,你可以在根组件中嵌套无限的视图树),可能会出现StackoverflowException(VM运行时没有足够的内存空间来放置另一个调用)。React-Native依赖于自定义视图组件ReactRootView,如果渲染了无限/过于昂贵的视图树,则会抛出您看到的异常。RN应用程序的结构是一个Android活动,带有一个ReactRootView(framelayout子类),其中包含您在JS中添加的所有内容。每个屏幕。因此,如果您的一个屏幕渲染了太多次,并且您渲染了另一个屏幕,您就会达到ReactRootView溢出内存堆栈的点,然后就会出现异常。

您在旧手机上看到这个问题,可能是因为设备规格低于您的渲染过程对其施加的压力,或者因为RN的视图生成代码上的特定错误在4.4.2上被暴露出来。

尝试使用why-did-you-render等渲染评估工具来检测不需要的渲染周期。否则,您需要减少渲染次数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接