Skip to content

Commit 7dc1998

Browse files
committed
fix: handle multiple dirty fragments on dispose
1 parent e4f5e0f commit 7dc1998

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/tabs/tabs.android.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ function initializeNativeClasses() {
206206
this.mCurTransaction = fragmentManager?.beginTransaction();
207207
}
208208

209-
const index = this.owner.fragments.indexOf(fragment);
209+
// detached fragments are still attached to the fragment manager
210+
// const index = this.owner.fragments.indexOf(fragment);
210211
// if (index !== -1) {
211212
// this.owner.fragments.splice(index, 1);
212213
// }
@@ -620,22 +621,26 @@ export class Tabs extends TabsBase {
620621
}
621622

622623
private disposeCurrentFragments(): void {
623-
let fragmentManager: androidx.fragment.app.FragmentManager;
624+
// we need to use this because the destroyItem only detaches the item
625+
// here we clean up all fragments, even ones that were detached to another manager, which may happen on suspend/resume
626+
// alternative: actually remove the fragment on destroyItem
627+
const transactionMap = new Map<androidx.fragment.app.FragmentManager, androidx.fragment.app.FragmentTransaction>();
624628
for (const fragment of this.fragments) {
625-
fragmentManager = this._getParentFragmentManagerFromFragment(fragment);
626-
if (fragmentManager) {
627-
break;
629+
const fragmentManager = this._getParentFragmentManagerFromFragment(fragment);
630+
if (!fragmentManager || fragmentManager.isDestroyed()) {
631+
continue;
628632
}
629-
}
630-
if (fragmentManager) {
631-
const transaction = fragmentManager.beginTransaction();
632-
633-
const fragments = this.fragments;
634-
for (let i = 0; i < fragments.length; i++) {
635-
transaction.remove(fragments[i]);
633+
if (!transactionMap.has(fragmentManager)) {
634+
transactionMap.set(fragmentManager, fragmentManager.beginTransaction());
636635
}
636+
const transaction = transactionMap.get(fragmentManager);
637+
638+
transaction.remove(fragment);
639+
}
640+
for (const transaction of transactionMap.values()) {
637641
transaction.commitNowAllowingStateLoss();
638642
}
643+
transactionMap.clear(); // let's avoid memory leaks
639644
this.fragments = [];
640645
}
641646

0 commit comments

Comments
 (0)