只有一个回调可以注册到本机模块中的函数反应本机错误
Only one callback may be registered to a function in a native module react native error
我最近向我添加了一个 android 本机模块,它侦听来自系统的时区和时间更改广播,并允许应用程序执行一些操作。本机模块看起来像这样
public class TimezoneHandlerModule extends ReactContextBaseJavaModule {
private final Context context;
private final TimezoneChangeBroadcastReceiver timezoneChangeBroadcastReceiver;
private Callback onTimezoneChangeCallback;
public TimezoneHandlerModule(ReactApplicationContext reactContext) {
super(reactContext);
this.context = reactContext;
this.timezoneChangeBroadcastReceiver = new TimezoneChangeBroadcastReceiver();
}
private void registerForTimezoneChangeHandler() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getReactApplicationContext().registerReceiver(timezoneChangeBroadcastReceiver, intentFilter);
}
private void unregisterTimezoneChangeHandler() {
getReactApplicationContext().unregisterReceiver(timezoneChangeBroadcastReceiver);
}
public void setOnTimezoneChangeCallback(Callback onTimezoneChangeCallback) {
this.onTimezoneChangeCallback = onTimezoneChangeCallback;
}
/**
* @return the name of this module. This will be the name used to {@code require()} this module
* from javascript.
*/
@Override
public String getName() {
return "TimezoneHandler";
}
@ReactMethod
public void start(Callback onChange) {
Log.d(getName(), "Starting the timezone change handler");
this.registerForTimezoneChangeHandler();
this.setOnTimezoneChangeCallback(onChange);
}
@ReactMethod
public void stop() {
Log.d(getName(), "Stopping the timezone change handler");
this.unregisterTimezoneChangeHandler();
}
private class TimezoneChangeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(getName(), "Received broadcast for timezone/time change " + intent.getAction());
final String action = intent.getAction();
if (action.equals(Intent.ACTION_TIME_CHANGED) || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
TimezoneHandlerModule.this.onTimezoneChangeCallback.invoke();
}
}
}
}
公开了两个 React 方法 start
和 stop
。 start
将函数作为参数,每当接收到时区更改或时间更改的广播时调用该函数。连接本机模块并在模拟器中启动应用程序后,我打开 Settings
并更改时区,可以看到打印了相关日志。
11-24 17:07:21.837 1597-1597/com.xyz D/TimezoneHandler: Received broadcast for timezone/time change
11-24 17:07:21.837 1597-1907/com.xyz I/ReactNativeJS: Detected timezone change
当我再次更改时区时,我在 logcat 输出中看到以下错误
1-24 17:22:42.356 1597-1597/com.galarmapp D/TimezoneHandler: Received broadcast for timezone/time change
11-24 17:22:42.365 1597-1907/com.galarmapp E/ReactNativeJS: The callback start() exists in module TimezoneHandler, but only one callback may be registered to a function in a native module.
11-24 17:22:42.367 1597-1908/com.galarmapp E/unknown:React: The callback start() exists in module TimezoneHandler, but only one callback may be registered to a function in a native module., stack:
__invokeCallback@12814:10
<unknown>@12685:24
guard@12604:3
invokeCallbackAndReturnFlushedQueue@12684:6
从错误消息来看,似乎我正在尝试将单独的回调附加到 start
函数,但我没有做任何此类事情。我在顶级组件的 componentWillMount
中调用 start
方法,并确认它没有被调用两次。我看到其他人在尝试不同的事情时也看到了这个错误,但仍然不明白问题背后的原因。
如果您有任何见解,请分享。
根据文档 http://facebook.github.io/react-native/docs/native-modules-android.html#callbacks - "A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later." 一旦您对回调执行了 invoke() 操作,就无法再次使用它。
通过将事件发送到 javascript 可以更好地解决这种时区更改的特殊用例。请参阅此文档 http://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
我最近向我添加了一个 android 本机模块,它侦听来自系统的时区和时间更改广播,并允许应用程序执行一些操作。本机模块看起来像这样
public class TimezoneHandlerModule extends ReactContextBaseJavaModule {
private final Context context;
private final TimezoneChangeBroadcastReceiver timezoneChangeBroadcastReceiver;
private Callback onTimezoneChangeCallback;
public TimezoneHandlerModule(ReactApplicationContext reactContext) {
super(reactContext);
this.context = reactContext;
this.timezoneChangeBroadcastReceiver = new TimezoneChangeBroadcastReceiver();
}
private void registerForTimezoneChangeHandler() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getReactApplicationContext().registerReceiver(timezoneChangeBroadcastReceiver, intentFilter);
}
private void unregisterTimezoneChangeHandler() {
getReactApplicationContext().unregisterReceiver(timezoneChangeBroadcastReceiver);
}
public void setOnTimezoneChangeCallback(Callback onTimezoneChangeCallback) {
this.onTimezoneChangeCallback = onTimezoneChangeCallback;
}
/**
* @return the name of this module. This will be the name used to {@code require()} this module
* from javascript.
*/
@Override
public String getName() {
return "TimezoneHandler";
}
@ReactMethod
public void start(Callback onChange) {
Log.d(getName(), "Starting the timezone change handler");
this.registerForTimezoneChangeHandler();
this.setOnTimezoneChangeCallback(onChange);
}
@ReactMethod
public void stop() {
Log.d(getName(), "Stopping the timezone change handler");
this.unregisterTimezoneChangeHandler();
}
private class TimezoneChangeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(getName(), "Received broadcast for timezone/time change " + intent.getAction());
final String action = intent.getAction();
if (action.equals(Intent.ACTION_TIME_CHANGED) || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
TimezoneHandlerModule.this.onTimezoneChangeCallback.invoke();
}
}
}
}
公开了两个 React 方法 start
和 stop
。 start
将函数作为参数,每当接收到时区更改或时间更改的广播时调用该函数。连接本机模块并在模拟器中启动应用程序后,我打开 Settings
并更改时区,可以看到打印了相关日志。
11-24 17:07:21.837 1597-1597/com.xyz D/TimezoneHandler: Received broadcast for timezone/time change
11-24 17:07:21.837 1597-1907/com.xyz I/ReactNativeJS: Detected timezone change
当我再次更改时区时,我在 logcat 输出中看到以下错误
1-24 17:22:42.356 1597-1597/com.galarmapp D/TimezoneHandler: Received broadcast for timezone/time change
11-24 17:22:42.365 1597-1907/com.galarmapp E/ReactNativeJS: The callback start() exists in module TimezoneHandler, but only one callback may be registered to a function in a native module.
11-24 17:22:42.367 1597-1908/com.galarmapp E/unknown:React: The callback start() exists in module TimezoneHandler, but only one callback may be registered to a function in a native module., stack:
__invokeCallback@12814:10
<unknown>@12685:24
guard@12604:3
invokeCallbackAndReturnFlushedQueue@12684:6
从错误消息来看,似乎我正在尝试将单独的回调附加到 start
函数,但我没有做任何此类事情。我在顶级组件的 componentWillMount
中调用 start
方法,并确认它没有被调用两次。我看到其他人在尝试不同的事情时也看到了这个错误,但仍然不明白问题背后的原因。
如果您有任何见解,请分享。
根据文档 http://facebook.github.io/react-native/docs/native-modules-android.html#callbacks - "A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later." 一旦您对回调执行了 invoke() 操作,就无法再次使用它。
通过将事件发送到 javascript 可以更好地解决这种时区更改的特殊用例。请参阅此文档 http://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript