Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send data from Android activity to React Native

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.

like image 462
tepsijash Avatar asked Dec 11 '22 08:12

tepsijash


2 Answers

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);
        }
    });
}
like image 58
AlVelig Avatar answered Dec 28 '22 07:12

AlVelig


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!

like image 31
tepsijash Avatar answered Dec 28 '22 08:12

tepsijash