您的位置:

解决方案:react-native RuntimeException("Illegal callback invocation from native "+ "module. This callback type only permits a single invocation from "+ "native code.")

  发布时间:2025-04-05 14:51:00
在React Native中出现Illegal callback invocation from native module问题通常是由于原生代码多次调用JavaScript回调函数引起的,解决方法包括保证回调只调用一次、升级React Native版本、使用Promise替代回调、正确处理回调生命周期、避免在不同线程中调用回调,具体例子可以通过添加标记确保回调只被触发一次

问题原因

这个问题通常是由于在 React Native 中的 JavaScript 回调函数被不正确地多次调用引起的。在某些情况下,原生代码会尝试多次调用 JavaScript 回调函数,但是该回调函数不支持被多次调用,因此会抛出 "Illegal callback invocation from native module" 的 RuntimeException。这个问题通常发生在与原生模块的交互过程中。

解决方案

在React Native中出现RuntimeException("Illegal callback invocation from native module. This callback type only permits a single invocation from native code.")通常是因为在 native code 中尝试多次调用 JavaScript 回调函数。这种情况在 React Native 模块的开发中可能会经常遇到。 为了解决这个问题,可以尝试以下几种方法: 1. 使用回调只调用一次:确保在 native code 中回调 JavaScript 时只调用了一次。如果有多个地方需要调用 JavaScript 回调函数,可以考虑将这些调用合并为一个单独的回调。 2. 使用最新版本的 React Native:有时这个问题可能是由于 React Native 的 bug 导致的,因此尝试升级到最新版本的 React Native 可能会解决这个问题。 3. 使用 Promise 替代回调:在一些情况下,使用 Promise 可能比使用回调更好。可以尝试用 Promise 来处理异步操作,避免多次调用同一个回调函数的问题。 4. 正确处理回调生命周期:确保在 native code 中正确处理 JavaScript 回调函数的生命周期,避免重复调用或意外销毁回调函数。 5. 避免在不同线程中调用回调:确保在正确的线程中调用 JavaScript 回调函数,避免多线程操作导致的问题。 举例:假设我有一个自定义的 React Native 模块,其中有一个方法需要从原生模块中获取数据并回调给 JavaScript。正确的做法是在原生模块中只调用一次 JavaScript 回调函数,如下所示:


// 原生模块中的代码
public void fetchData(final Callback successCallback) {
    // 获取数据的异步操作
    getData(new DataCallback() {
        @Override
        public void onDataReceived(String data) {
            successCallback.invoke(data);  // 只调用一次JavaScript回调函数
        }
    });
}

通过采取上述方法,可以更好地解决在 React Native 中出现 "Illegal callback invocation from native module" 的 RuntimeException。

具体例子

在React Native中出现RuntimeException("Illegal callback invocation from native module. This callback type only permits a single invocation from native code.")通常是由于在与原生代码通信时,尝试多次调用回调函数造成的。这个问题通常会出现在调用原生模块的方法时,回调函数被不正确地多次触发。 要正确解决这个问题,可以在调用回调函数之前添加适当的检查,以确保回调函数只被触发一次。这可以通过添加一个标记来实现,标记表示回调函数是否已经被调用。在React Native中,可以使用Promise来管理异步操作,确保回调函数只被调用一次。 以下是一个示例代码,演示了如何在调用原生模块时避免多次触发回调函数的问题:


import { NativeModules } from 'react-native';

const { MyNativeModule } = NativeModules;

function fetchDataAndNotify(callback) {
  let isCallbackCalled = false;

  MyNativeModule.fetchData((data) => {
    if (!isCallbackCalled) {
      isCallbackCalled = true;
      callback(data);
    }
  });
}

// 调用示例
fetchDataAndNotify((data) => {
  console.log(data);
});

在上面的示例中,我们通过添加 isCallbackCalled 标记来确保回调函数只被调用一次。当从原生模块获取数据后,会检查该标记,如果回调函数已经被调用过一次,则不再执行。 通过这种方式,我们可以避免出现RuntimeException("Illegal callback invocation from native module. This callback type only permits a single invocation from native code.")的问题,确保回调函数只被触发一次。