I have an activity BasicReactActivity
which extends ReactActivity
. I use this activity as a base activity to host my react-native views. I have a use case where I am opening multiple instances of BasicReactActivity
one on top of the other. I face the following exception crash:
Fatal Exception: java.lang.AssertionError: Pausing an activity that is not the current activity, this is incorrect! Current activity: BasicReactActivity Paused activity: BasicReactActivity
at com.facebook.infer.annotation.Assertions.assertCondition(Assertions.java:72)
at com.facebook.react.ReactInstanceManager.onHostPause(ReactInstanceManager.java:549)
at com.facebook.react.ReactDelegate.onHostPause(ReactDelegate.java:63)
at com.facebook.react.ReactActivityDelegate.onPause(ReactActivityDelegate.java:95)
at com.facebook.react.ReactActivity.onPause(ReactActivity.java:51)
at com.apollorncontainer.activities.BasicReactActivity.onPause(BasicReactActivity.java:267)
at android.app.Activity.performPause(Activity.java:8142)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1508)
at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4726)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:4687)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4639)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:228)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2147)
at android.os.Handler.dispatchMessage(Handler.java:107)
Following is the code for my onResume()
and onPause()
of the BasicReactActivity
:
public static Object REACT_DELEGATE_LOCK = new Object();
@Override
protected void onPause() {
super.onPause();
Timber.d("{CrashDebug} Calling onPause for: " + getTag());
Timber.d("\n");
if(reactDelegate != null) {
try {
synchronized (REACT_DELEGATE_LOCK) {
reactDelegate.onHostPause();
}
} catch (Exception e) {
Timber.e(e);
}
}
}
@Override
protected void onResume() {
super.onResume();
Timber.d("{CrashDebug} Calling onResume for: " + getTag());
if(reactDelegate != null) {
synchronized (REACT_DELEGATE_LOCK) {
reactDelegate.onHostResume();
}
}
}
private String getTag() {
if(reactDelegate.getReactInstanceManager().getCurrentReactContext() != null &&
reactDelegate.getReactInstanceManager().getCurrentReactContext()
.getCurrentActivity() != null) {
return component + " : " + getReactNativeHost().getReactInstanceManager().getCurrentReactContext()
.getCurrentActivity() + " : " + this;
}
return component + " : null : " + this;
}
Few notes for the above code:
- I have added a lock around
reactDelegate
operations to avoid any concurrency between theonHostPause()
andonHostResume()
calls between two instances ofBasicReactActivity
getTag()
method is usedd to trace the current state in runtime.
In one of the crashes, I see the following logs:
Calling onResume for: ACCOUNT_BLOCKED : com.apollorncontainer.activities.BasicReactActivity@90a3e41 : com.apollorncontainer.activities.BasicReactActivity@90a3e41
Calling onResume for: ACCOUNT_BLOCKED : com.apollorncontainer.activities.BasicReactActivity@90a3e41 : com.apollorncontainer.activities.BasicReactActivity@b89a25c
Calling onPause for: ACCOUNT_BLOCKED : com.apollorncontainer.activities.BasicReactActivity@90a3e41 : com.apollorncontainer.activities.BasicReactActivity@b89a25c
Calling onResume for: POST_SIGNUP : com.apollorncontainer.activities.BasicReactActivity@96f6947 : com.apollorncontainer.activities.BasicReactActivity@96f6947
Calling onResume for: POST_SIGNUP : com.apollorncontainer.activities.BasicReactActivity@96f6947 : com.apollorncontainer.activities.BasicReactActivity@a9f057a
Calling onPause for: POST_SIGNUP : com.apollorncontainer.activities.BasicReactActivity@96f6947 : com.apollorncontainer.activities.BasicReactActivity@a9f057a
If we observe these two lines specifically:
Calling onResume for: ACCOUNT_BLOCKED : com.apollorncontainer.activities.BasicReactActivity@90a3e41 : com.apollorncontainer.activities.BasicReactActivity@b89a25c
Calling onPause for: ACCOUNT_BLOCKED : com.apollorncontainer.activities.BasicReactActivity@90a3e41 : com.apollorncontainer.activities.BasicReactActivity@b89a25c
Even after calling of onHostResume()
for instance b89a25c
, the mCurrentActivity
fetched from the ReactContext
does not change when onHostPause()
is called.
If we check the method onHostResume()
, only two things can cause this not to set:
getReactNativeHost().hasInstance()
returns false ORmLifecycleState != LifecycleState.BEFORE_RESUME
andmLifecycleState != LifecycleState.BEFORE_CREATE
(from ReactInstanceManager.moveToResumedLifecycleState)
Both above don't seem probable. Not sure, where is the problem here.
PS: I am using version 0.63.4
of react native.