Skip to content

Commit 4f5887b

Browse files
authored
fix(android): lollipop crash on changing activity context after navigation w/transition (#5700)
1 parent 1536d15 commit 4f5887b

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

tns-core-modules/ui/frame/frame.android.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { profile } from "../../profiling";
2222
// TODO: Remove this and get it from global to decouple builder for angular
2323
import { createViewFromEntry } from "../builder";
2424

25+
import { device } from "../../platform";
26+
import lazy from "../../utils/lazy";
27+
2528
export * from "./frame-common";
2629

2730
const INTENT_EXTRA = "com.tns.activity";
@@ -32,6 +35,8 @@ const CALLBACKS = "_callbacks";
3235
const ownerSymbol = Symbol("_owner");
3336
const activityRootViewsMap = new Map<number, WeakRef<View>>();
3437

38+
const sdkVersion = lazy(() => parseInt(device.sdkVersion));
39+
3540
let navDepth = -1;
3641
let fragmentId = -1;
3742
export let moduleLoaded: boolean;
@@ -186,13 +191,28 @@ export class Frame extends FrameBase {
186191
super.onUnloaded();
187192
}
188193

189-
private disposeCurrentFragment(){
190-
if (this._currentEntry && this._currentEntry.fragment) {
191-
const manager: android.app.FragmentManager = this._getFragmentManager();
192-
const transaction = manager.beginTransaction();
194+
private disposeCurrentFragment(): void {
195+
if (!this._currentEntry || !this._currentEntry.fragment) {
196+
return;
197+
}
198+
199+
const manager: android.app.FragmentManager = this._getFragmentManager();
200+
const transaction = manager.beginTransaction();
201+
const androidSdkVersion = sdkVersion();
202+
203+
if (androidSdkVersion !== 21 && androidSdkVersion !== 22) {
193204
transaction.remove(this._currentEntry.fragment);
194-
transaction.commitAllowingStateLoss();
205+
} else {
206+
// https://github.com/NativeScript/NativeScript/issues/5674
207+
// HACK: Add and remove dummy fragment to workaround a Lollipop issue
208+
// with inFragment passed as null when adding transition targets: https://android.googlesource.com/platform/frameworks/base.git/+/lollipop-release/core/java/android/app/BackStackRecord.java#1127
209+
const dummyFragmentTag = "dummy";
210+
const dummyFragment = this.createFragment(<BackstackEntry>{}, dummyFragmentTag);
211+
transaction.replace(this.containerViewId, dummyFragment, dummyFragmentTag);
212+
transaction.remove(dummyFragment);
195213
}
214+
215+
transaction.commitAllowingStateLoss();
196216
}
197217

198218
private createFragment(backstackEntry: BackstackEntry, fragmentTag: string): android.app.Fragment {

0 commit comments

Comments
 (0)