Var*_*pta 7 react-native react-native-android
我最近添加了一个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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
两个反应的方法被暴露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
Run Code Online (Sandbox Code Playgroud)
当我再次更改时区时,我在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
Run Code Online (Sandbox Code Playgroud)
从错误消息,似乎我试图附加一个单独的回调start函数,但我没有做任何这样的事情.我在顶级组件中调用start方法,componentWillMount并确认它没有被调用两次.我看到其他人在尝试不同的事情时也看到了这个错误,但仍然不明白问题背后的原因.
如果您有任何见解,请分享.
根据文档http://facebook.github.io/react-native/docs/native-modules-android.html#callbacks - "本机模块应该只调用一次它的回调.但是,它可以存储回调并稍后调用它." 在回调上完成invoke()后,就无法再次使用它.
通过向javascript发送事件可以更好地解决时区更改的这种特殊用例.请参阅此文档http://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
| 归档时间: |
|
| 查看次数: |
5032 次 |
| 最近记录: |