Skip to content

Commit 129b25a

Browse files
committed
fix(android): keep the root view when an activity replaces another
Android can start a new activity before the old one stops. When both activities use one root view, the old activity unloaded and destroyed the view that the new activity showed. The view also kept the old FragmentManager, so the screen stayed blank. onStop, onDestroy, and onSaveInstanceState now act only on a root view that the activity shows. A new activity unloads the view from the previous activity before it adopts the view, which clears the cached FragmentManager. An activity takes the view back when it starts again. Fixes #11615
1 parent e1ea59b commit 129b25a

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

‎packages/core/ui/frame/index.android.ts‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
881881
@profile
882882
public onSaveInstanceState(activity: androidx.appcompat.app.AppCompatActivity, outState: android.os.Bundle, superFunc: Function): void {
883883
superFunc.call(activity, outState);
884-
const rootView = this._rootView;
884+
const rootView = this.getRootViewShownBy(activity);
885885
if (rootView instanceof Frame) {
886886
outState.putInt(INTENT_EXTRA, rootView.android.frameId);
887887
rootView._saveFragmentsState();
@@ -926,6 +926,10 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
926926
}
927927

928928
const rootView = this._rootView;
929+
if (rootView && rootView._context !== activity && !isEmbedded()) {
930+
this.setActivityContent(activity, null, false);
931+
}
932+
929933
if (rootView && !rootView.isLoaded && !isEmbedded()) {
930934
rootView.callLoaded();
931935
}
@@ -939,7 +943,7 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
939943
Trace.write('NativeScriptActivity.onStop();', Trace.categories.NativeLifecycle);
940944
}
941945

942-
const rootView = this._rootView;
946+
const rootView = this.getRootViewShownBy(activity);
943947
if (rootView && rootView.isLoaded && !isEmbedded()) {
944948
rootView.callUnloaded();
945949
}
@@ -970,7 +974,7 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
970974
Trace.write('NativeScriptActivity.onDestroy();', Trace.categories.NativeLifecycle);
971975
}
972976

973-
const rootView = this._rootView;
977+
const rootView = this.getRootViewShownBy(activity);
974978
if (rootView) {
975979
rootView._tearDownUI(true);
976980
}
@@ -1088,6 +1092,10 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
10881092
Application.android.notify(resultArgs);
10891093
}
10901094

1095+
private getRootViewShownBy(activity: any): View | undefined {
1096+
return this._rootView?._context === activity ? this._rootView : undefined;
1097+
}
1098+
10911099
public resetActivityContent(activity: androidx.appcompat.app.AppCompatActivity, view?: View): void {
10921100
if (this._rootView) {
10931101
const manager = this._rootView._getFragmentManager();
@@ -1160,6 +1168,10 @@ export class ActivityCallbacksImplementation implements AndroidActivityCallbacks
11601168

11611169
activityRootViewsMap.set(rootView._domId, new WeakRef(rootView));
11621170

1171+
if (rootView.isLoaded && rootView._context !== activity && !isEmbedded()) {
1172+
rootView.callUnloaded();
1173+
}
1174+
11631175
// setup view as styleScopeHost
11641176
rootView._setupAsRootView(activity);
11651177

0 commit comments

Comments
 (0)