Skip to content

Reload (from dev menu) should call onHostDestroy or any other event to detect Reload #9773

@mauron85

Description

@mauron85

Thank you guys for amazing work

Issue Description

I'm developing react-native-background-geolocation. While working on this issue, I've identified potential problem within my module logic and Reload (from dev menu) functionality.

In my module I'm creating LocationService similar to android MessengerService from android examples.
In BackgroundGeolocationModule I'm binding to this service (and starting it) on user request (from js). Module should unbind from service on onHostDestroy (LifecycleEventListener) method (this part is not in my repo yet).

However it seems Reload doesn't call onHostDestroy or any other event to detect Reload event. As result client (module) client will be binding to service twice, which leads to java.lang.IllegalStateException: "This message is already in use" and app crash.

AndroidRuntime  D  Shutting down VM
                E  FATAL EXCEPTION: main
                E  Process: com.marianhello.RNBGExample, PID: 11937
                E  Theme: themes:{default=overlay:com.resurrectionremix.pitchblack, fontPkg:com.resurrectionremix.pitchblack, com.android.systemui=overlay:com.resurrectio
                   nremix.pitchblack, com.android.systemui.navbar=overlay:com.resurrectionremix.pitchblack}
                E  java.lang.IllegalStateException: { when=0 what=4 target=com.marianhello.react.BackgroundGeolocationModule$IncomingHandler } This message is already in 
                   use.
                E      at android.os.MessageQueue.enqueueMessage(MessageQueue.java:538)
                E      at android.os.Handler.enqueueMessage(Handler.java:631)
                E      at android.os.Handler.sendMessageAtTime(Handler.java:600)
                E      at android.os.Handler.sendMessageDelayed(Handler.java:570)
                E      at android.os.Handler.sendMessage(Handler.java:507)
                E      at android.os.Handler$MessengerImpl.send(Handler.java:721)
                E      at android.os.Messenger.send(Messenger.java:57)
                E      at com.marianhello.bgloc.LocationService.sendClientMessage(LocationService.java:369)
                E      at com.marianhello.bgloc.LocationService.handleLocation(LocationService.java:348)
                E      at com.marianhello.bgloc.AbstractLocationProvider.handleLocation(AbstractLocationProvider.java:81)
                E      at com.tenforwardconsulting.bgloc.DistanceFilterLocationProvider.onLocationChanged(DistanceFilterLocationProvider.java:318)
                E      at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:285)
                E      at android.location.LocationManager$ListenerTransport.-wrap0(LocationManager.java)
                E      at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:230)
                E      at android.os.Handler.dispatchMessage(Handler.java:102)
                E      at android.os.Looper.loop(Looper.java:148)
                E      at android.app.ActivityThread.main(ActivityThread.java:5461)
                E      at java.lang.reflect.Method.invoke(Native Method)
                E      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                E      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 unknown:React  W  Calling JS function after bridge has been destroyed.

Steps to Reproduce / Code Snippets

  1. Create android Service similar to MessengerService
  2. In ReactContextBaseJavaModule bind to it.
...
void doBindService() {
    // Establish a connection with the service.  We use an explicit
    // class name because there is no reason to be able to let other
    // applications replace our component.
    if (mIsBound) { return; } //member variable to prevent client to bind multiple times, but doesn't help when Reload is done (Module is reinstantiated so it is false again)

    mMessenger = new Messenger(new IncomingHandler());

    final Activity currentActivity = this.getCurrentActivity();
    Intent locationServiceIntent = new Intent(currentActivity, LocationService.class);
    locationServiceIntent.putExtra("config", mConfig);
    currentActivity.bindService(locationServiceIntent, mConnection, Context.BIND_IMPORTANT);
  }
...
  1. In some point. Do app Reload from dev menu
  2. Send some IPC Message from Service to client.
  3. App will crash, because client was registered twice, so same Message was sent twice to same client (which is illegal action in Android)

Expected Results

Event that is sent before react-native will do Reload, so we can unbind from service.

Additional Information

Addtional description also here:
http://stackoverflow.com/questions/39354236/android-how-to-prevent-binding-to-remote-messenger-service-twice-to-prevent-java?noredirect=1#comment66039454_39354236

  • React Native version: 0.29
  • Platform(s) (iOS, Android, or both?): Android
  • Operating System (macOS, Linux, or Windows?): all

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions