From c018252eee838f85ee84d43f5b58c9995e5aeb59 Mon Sep 17 00:00:00 2001 From: Lyubo Marinov Date: Fri, 9 Mar 2018 13:19:28 -0600 Subject: [PATCH] [Android] Fix RuntimeException in RNImmersiveModule java.lang.RuntimeException: Tried to access a JS module before the React instance was fully set up. Calls to ReactContext#getJSModule should only happen once initialize() has been called on your native module. at com.facebook.react.bridge.ReactContext.getJSModule(ReactContext.java:102) at com.rnimmersive.RNImmersiveModule.emitImmersiveStateChangeEvent(RNImmersiveModule.java:74) at org.jitsi.meet.sdk.JitsiMeetView.onWindowFocusChanged(JitsiMeetView.java:504) at android.view.View.dispatchWindowFocusChanged(View.java:10257) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1193) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:1197) at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3602) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) --- .../org/jitsi/meet/sdk/JitsiMeetView.java | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java b/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java index 18f06ac3a..2ed2b4588 100644 --- a/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java +++ b/android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java @@ -25,6 +25,7 @@ import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; import android.widget.FrameLayout; import com.facebook.react.ReactInstanceManager; @@ -53,6 +54,12 @@ public class JitsiMeetView extends FrameLayout { */ private static final int BACKGROUND_COLOR = 0xFF111111; + /** + * The {@link Log} tag which identifies the source of the log messages of + * {@code JitsiMeetView}. + */ + private final static String TAG = JitsiMeetView.class.getSimpleName(); + /** * React Native bridge. The instance manager allows embedding applications * to create multiple root views off the same JavaScript bundle. @@ -266,13 +273,15 @@ public class JitsiMeetView extends FrameLayout { * @param params {@code WritableMap} optional ancillary data for the event. */ private static void sendEvent( - String eventName, @Nullable WritableMap params) { + String eventName, + @Nullable WritableMap params) { if (reactInstanceManager != null) { ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); if (reactContext != null) { reactContext - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .getJSModule( + DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); } } @@ -498,10 +507,29 @@ public class JitsiMeetView extends FrameLayout { super.onWindowFocusChanged(hasFocus); // https://github.com/mockingbot/react-native-immersive#restore-immersive-state + + // FIXME The singleton pattern employed by RNImmersiveModule is not + // advisable because a react-native mobule is consumable only after its + // BaseJavaModule#initialize() has completed and here we have no + // knowledge of whether the precondition is really met. RNImmersiveModule immersive = RNImmersiveModule.getInstance(); if (hasFocus && immersive != null) { - immersive.emitImmersiveStateChangeEvent(); + try { + immersive.emitImmersiveStateChangeEvent(); + } catch (RuntimeException re) { + // FIXME I don't know how to check myself whether + // BaseJavaModule#initialize() has been invoked and thus + // RNImmersiveModule is consumable. A safe workaround is to + // swallow the failure because the whole full-screen/immersive + // functionality is brittle anyway, akin to the icing on the + // cake, and has been working without onWindowFocusChanged for a + // very long time. + Log.e( + TAG, + "RNImmersiveModule#emitImmersiveStateChangeEvent() failed!", + re); + } } }