You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native仅Android7.x触发ModuleHolder.getModule类ANR问题

Android 7.x 系列系统React Native偶发ANR问题

问题现象

近期仅在Android 7/7.1/7.1.1系统上偶现ANR问题,具体堆栈信息如下:

Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)

"main" prio=5 tid=1 Waiting

at java.lang.Object.wait! (Native method)
  at com.facebook.react.bridge.ModuleHolder.getModule (ModuleHolder.java:14)
  at com.facebook.react.bridge.NativeModuleRegistry.getModule (NativeModuleRegistry.java:11)
  at com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule (CatalystInstanceImpl.java:5)
  at com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule (CatalystInstanceImpl.java:1)
  at com.facebook.internal.instrument.InstrumentUtility.getUIManager (InstrumentUtility.java:4)
  at com.facebook.react.ReactInstanceManager.attachRootViewToInstance (ReactInstanceManager.java:4)
  at com.facebook.react.ReactRootView.attachToReactInstanceManager (ReactRootView.java:12)
  at com.facebook.react.ReactRootView.startReactApplication (ReactRootView.java:9)
  at com.myapp.ReactActivity.onCreate (ReactActivity.java:191)
  at android.app.Activity.performCreate (Activity.java:6845)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1119)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2700)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2808)
  at android.app.ActivityThread.-wrap12 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1541)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:165)
  at android.app.ActivityThread.main (ActivityThread.java:6375)
  at java.lang.reflect.Method.invoke! (Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:912)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:802)

"Jit thread pool worker thread 0" prio=5 tid=2 Native (still starting up)
  #00  pc 000000000001c0ac  /system/lib64/libc.so (syscall+28)
  #00  pc 00000000000e6dd4  /system/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+160)
  #00  pc 0000000000463cc4  /system/lib64/libart.so (art::ThreadPool::GetTask(art::Thread*)+252)
  #00  pc 0000000000463180  /system/lib64/libart.so (art::ThreadPoolWorker::Run()+124)
  #00  pc 0000000000462ab0  /system/lib64/libart.so (art::ThreadPoolWorker::Callback(void*)+116)
  #00  pc 0000000000068440  /system/lib64/libc.so (__pthread_start(void*)+196)
  #00  pc 000000000001dd70  /system/lib64/libc.so (__start_thread+16)

"HeapTaskDaemon" daemon prio=5 tid=7 Blocked

  #00  pc 000000000001beec  /system/lib64/libc.so (syscall+28)
  #00  pc 00000000000e8148  /system/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+160)
  #00  pc 0000000000240ee8  /system/lib64/libart.so (art::gc::TaskProcessor::GetTask(art::Thread*)+360)
  #00  pc 00000000002417c4  /system/lib64/libart.so (art::gc::TaskProcessor::RunAllTasks(art::Thread*)+92)
  #00  pc 00000000001e5530  /system/framework/arm64/boot-core-libart.oat (Java_dalvik_system_VMRuntime_runHeapTasks__+124)
  at dalvik.system.VMRuntime.runHeapTasks (Native method)
  at java.lang.Daemons$HeapTaskDaemon.run (Daemons.java:435)
  at java.lang.Thread.run (Thread.java:760)

....Many more thread in WAITING state

环境信息

系统信息:
OS: macOS 11.4
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @2.60GHz
内存: 115.29 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
二进制工具:
Node: 14.5.0 - ~/.nvm/versions/node/v14.5.0/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v14.5.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDK信息:
iOS SDK: 支持平台:DriverKit 21.0.1, iOS 15.0, macOS 12.0, tvOS 15.0, watchO 8.0
IDE信息:
Xcode: 13.1/13A1030d - /usr/bin/xcodebuild
npm依赖包:
react: 16.9.0 => 16.9.0
react-native: 0.61.4 => 0.61.4
npm全局包:
react-native-cli: 2.0.1

复现条件

目前无法稳定复现,已知问题仅在Android7.x系统上偶发,触发时机为调用rootView.startReactApplication(...)时。在Application的onCreate生命周期中,通过createReactContextInBackground()初始化了两个不同的React Instance Manager分别承载两个不同业务功能,第二个实例是在本次新版本中新增引入的。


根因分析

  1. 主线程卡在ModuleHolder.getModule的native wait调用上,是React Native 0.61.x版本多ReactInstanceManager场景下的已知锁竞争问题。两个实例并行初始化时,NativeModule初始化流程会争抢全局锁,当主线程调用startReactApplication需要获取UIManager模块时,锁被另一个初始化线程持有,就会进入无限等待。
  2. Android 7.x的ART虚拟机锁调度、堆任务优先级策略和高版本系统有差异,HeapTaskDaemon等系统线程更容易抢占锁资源,放大了锁等待的概率,最终触发ANR超时。

修复方案

方案1:调整实例初始化时机

不要在Application onCreate中同时初始化两个ReactInstanceManager,采用懒加载策略:

  • 保留核心业务对应的实例在Application层预初始化
  • 第二个新增实例延迟到对应业务场景启动前再初始化,或者通过IdleHandler在主线程空闲时触发初始化,避免和主流程争抢资源。

方案2:修复React Native版本缺陷

你当前使用的0.61.4版本存在多实例锁死的已知缺陷,可二选一处理:

  • 升级React Native到0.63.0及以上版本,官方已在该版本修复了ModuleHolder.getModule的死锁问题
  • 若暂时无法升级版本,可自行给ModuleHolder类打补丁,移除初始化过程中不必要的同步锁,或者给wait调用添加超时逻辑,避免主线程无限等待。

方案3:Android 7.x专属优化

针对Android 7.x系统做适配,禁用堆任务守护线程抢占锁:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
    try {
        Class<?> vmRuntimeClazz = Class.forName("dalvik.system.VMRuntime");
        Method getRuntimeMethod = vmRuntimeClazz.getMethod("getRuntime");
        Object runtimeInstance = getRuntimeMethod.invoke(null);
        Method setHeapTaskDaemonEnabledMethod = vmRuntimeClazz.getMethod("setHeapTaskDaemonEnabled", boolean.class);
        setHeapTaskDaemonEnabledMethod.invoke(runtimeInstance, false);
    } catch (Exception e) {
        // 异常不影响主流程,可直接忽略
    }
}

将上述代码添加到Application的onCreate方法中即可。

方案4:调用逻辑优化

调用startReactApplication前先判断对应ReactInstanceManager的上下文是否初始化完成,若还在初始化流程中,先展示占位加载UI,等初始化成功回调触发后再绑定RootView,避免主线程阻塞。


内容的提问来源于stack exchange,提问作者Rishabh876

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 23:45:04