I am handling an intent in a native android activity and would like to send the data obtained within the intent to the react native part. Please excuse my poor terminology/explanations - I am a complete beginner when it comes to Android development.
I have tried following this guide: https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript, but I get stuck on getting the main react context. So, the intent is coming outside of the app, and I would like to get the intent data and start the app. E.g. the main view should only display the text from intent.
This is how I send the event:
public class CustomActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WritableMap map = Arguments.createMap();
map.putString("messageString", "CustomMessage");
try {
getReactInstanceManager().getCurrentReactContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("customEvent", map);
} catch (Exception e){
Log.e("ReactNative", "Caught Exception: " + e.getMessage());
}
}
This throws an exception
Caught Exception: Attempt to invoke virtual method 'com.facebook.react.bridge.JavaScriptModule com.facebook.react.bridge.ReactContext.getJSModule(java.lang.Class)' on a null object reference
I am not defining a custom layout for the activity and would like to use the main app's context.
I encountered in production a couple of
Fatal Exception: java.lang.RuntimeException
Unable to resume activity {minibar.android/minibar.android.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.facebook.react.bridge.JavaScriptModule com.facebook.react.bridge.ReactContext.getJSModule(java.lang.Class)' on a null object reference
Caused by java.lang.NullPointerException
Attempt to invoke virtual method 'com.facebook.react.bridge.JavaScriptModule com.facebook.react.bridge.ReactContext.getJSModule(java.lang.Class)' on a null object reference
So the solution was to check if reactContext
is not null otherwise create listener and wait for it:
ReactInstanceManager reactInstanceManager = getReactNativeHost().getReactInstanceManager();
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if(reactContext != null) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("url", params);
} else {
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext context) {
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("url", params);
reactInstanceManager.removeReactInstanceEventListener(this);
}
});
}
So it seems like this fails because the context does not get created in time. To solve this I added a busy wait for the context to be created.
while (getReactInstanceManager().getCurrentReactContext() == null); // Busy wait.
getReactInstanceManager().getCurrentReactContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("defineIntent", map);
If someone knows a better way to deal with the wait, please update it here. Thank you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With