Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native - how can I emit an event to RN from MainActivity.java?

In the React Native AppState library:
iOS has three states background->inactive->active
Android only has background->active

When an Android app is fully backgrounded the MainActivity goes from onPause -> onStop

When there is a System Notification e.g. an In app purchase it goes to onPause

I need to run some code when the app goes from background to the foreground
onStop -> onResume

I don't want it to run if the app was briefly paused because of a system notification
onPause -> onResume

Is this possible? The lifecycle events for React do not have an onHostStop

I tried emitting an event from MainActivity for each Activity lifecycle event but that caused the App to crash with a null pointer exception.

Is it even possible to emit an event to React Native from MainActivity?

Thanks

EDIT Added code to show attempt to emit event from MainActivity

MainActivity.java snippet

import com.facebook.react.ReactActivity;
import com.facebook.react.modules.core.DeviceEventManagerModule;

public class MainActivity extends ReactActivity {

    DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter;

    @Override
    public void onStop() {
        super.onStop();
        eventEmitter.emit("onStop", "ActivityonStop");
    }
}

React Native

const nativeEventListener = DeviceEventEmitter.addListener('onStop',
  (e)=>{
    console.log("NATIVE_EVENT");
    dispatch({type: "NATIVE_EVENT"})
})

error in logcat

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.realer.android, PID: 15251
java.lang.RuntimeException: Unable to stop activity {com.realer.android/com.realer.android.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.facebook.react.modules.core.DeviceEventManagerModule$RCTDeviceEventEmitter.emit(java.lang.String, java.lang.Object)' on a null object reference
   at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3837)
   at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3886)
   at android.app.ActivityThread.-wrap25(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:6077)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.facebook.react.modules.core.DeviceEventManagerModule$RCTDeviceEventEmitter.emit(java.lang.String, java.lang.Object)' on a null object reference
   at com.realer.android.MainActivity.onStop(MainActivity.java:40)
   at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1289)
   at android.app.Activity.performStop(Activity.java:6839)
   at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3834)
   at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3886) 
   at android.app.ActivityThread.-wrap25(ActivityThread.java) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:154) 
   at android.app.ActivityThread.main(ActivityThread.java:6077) 
   at java.lang.reflect.Method.invoke(Native Method)
like image 451
Brien Crean Avatar asked Nov 30 '16 21:11

Brien Crean


People also ask

What is the difference between React Native and React Native events?

For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules. Events are described in detail in this article.

Is there an onhoststop event for activity lifecycle events in React Native?

The lifecycle events for React do not have an onHostStop I tried emitting an event from MainActivity for each Activity lifecycle event but that caused the App to crash with a null pointer exception. Is it even possible to emit an event to React Native from MainActivity?

How do I add react native to Android app?

Open up your MainApplication.java or MainApplication.kt file, which can be found in the following path: android/app/src/main/java/com/your-app-name/. Locate ReactNativeHost’s getPackages () method and add your package to the packages list getPackages () returns:

What is event listener in React Native?

Event Listener is an important part of JavaScript where UI responds according to an event that occurs. Event listeners wait for an event to occur and pass that event across different files. It helps us to add interactive functionality to our react native app by listening to the events. Let’s see an example of Event Listener in React Native hooks.


1 Answers

Try updating your MainActivity.java like this:

public class MainActivity extends ReactActivity {

    @Override
    public void onStop() {
        super.onStop();

        WritableMap params = Arguments.createMap(); // add here the data you want to send
        params.putString("event", "ActivityonStop"); // <- example

        getReactInstanceManager().getCurrentReactContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("onStop", params);
    }
}

Let me know if this works. In my apps I usually send the events from a class that extends ReactContextBaseJavaModule where I can access the context just by calling getReactApplicationContext(), but it seems that it might work if you can obtain the ReactContext from the ReactInstanceManager.

like image 124
Andrei Pitea Avatar answered Sep 18 '22 14:09

Andrei Pitea