Skip to content

Commit b86d2fe

Browse files
author
farfromrefug
committed
fix(android): potential memory leaks fix
1 parent 8d003b2 commit b86d2fe

File tree

4 files changed

+58
-43
lines changed

4 files changed

+58
-43
lines changed

src/bottomnavigationbar/bottomnavigationbar.android.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare type OnNavigationItemSelectedListener = com.google.android.material.bott
1616
declare type OnNavigationItemReselectedListener = com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemReselectedListener;
1717

1818
// Listeners
19-
type OnTabSelectedlistener = new (owner: BottomNavigationBar) => OnNavigationItemSelectedListener;
19+
type OnTabSelectedlistener = new (owner: WeakRef<BottomNavigationBar>) => OnNavigationItemSelectedListener;
2020

2121
// eslint-disable-next-line no-redeclare
2222
let OnTabSelectedlistener: OnTabSelectedlistener;
@@ -29,24 +29,26 @@ const getOnTabSelectedlistener = () => {
2929
@NativeClass
3030
@Interfaces([com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemSelectedListener])
3131
class OnTabSelectedlistenerImpl extends java.lang.Object implements OnNavigationItemSelectedListener {
32-
constructor(public owner: BottomNavigationBar) {
32+
constructor(public owner: WeakRef<BottomNavigationBar>) {
3333
super();
34-
3534
// necessary when extending TypeScript constructors
3635
return global.__native(this);
3736
}
3837

3938
public onNavigationItemSelected(menuItem: globalAndroid.view.MenuItem): boolean {
40-
const index = menuItem.getItemId();
41-
const bottomNavigationTab = this.owner.items[index];
42-
43-
if (bottomNavigationTab.isSelectable) {
44-
this.owner._emitTabSelected(index);
45-
} else {
46-
this.owner._emitTabPressed(index);
39+
const owner = this.owner?.get();
40+
if (owner) {
41+
const index = menuItem.getItemId();
42+
const bottomNavigationTab = owner.items[index];
43+
44+
if (bottomNavigationTab.isSelectable) {
45+
owner._emitTabSelected(index);
46+
} else {
47+
owner._emitTabPressed(index);
48+
}
49+
return bottomNavigationTab.isSelectable;
4750
}
48-
49-
return bottomNavigationTab.isSelectable;
51+
return false;
5052
}
5153
}
5254

@@ -55,7 +57,7 @@ const getOnTabSelectedlistener = () => {
5557
return OnTabSelectedlistener;
5658
};
5759

58-
type OnTabReselectedListener = new (owner: BottomNavigationBar) => OnNavigationItemReselectedListener;
60+
type OnTabReselectedListener = new (owner: WeakRef<BottomNavigationBar>) => OnNavigationItemReselectedListener;
5961

6062
// eslint-disable-next-line no-redeclare
6163
let OnTabReselectedListener: OnTabReselectedListener;
@@ -67,15 +69,14 @@ const getOnTabReselectedListener = () => {
6769
@NativeClass
6870
@Interfaces([com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemReselectedListener])
6971
class OnTabReselectedListenerImpl extends java.lang.Object implements OnNavigationItemReselectedListener {
70-
constructor(public owner: BottomNavigationBar) {
72+
constructor(public owner: WeakRef<BottomNavigationBar>) {
7173
super();
72-
7374
// necessary when extending TypeScript constructors
7475
return global.__native(this);
7576
}
7677

7778
public onNavigationItemReselected(menuItem: globalAndroid.view.MenuItem): void {
78-
this.owner._emitTabReselected(menuItem.getItemId());
79+
this.owner?.get()?._emitTabReselected(menuItem.getItemId());
7980
}
8081
}
8182

@@ -115,8 +116,9 @@ export class BottomNavigationBar extends BottomNavigationBarBase {
115116
super.initNativeView();
116117
const OnTabReselectedListener = getOnTabReselectedListener();
117118
const OnTabSelectedListener = getOnTabSelectedlistener();
118-
this.reselectListener = new OnTabReselectedListener(this);
119-
this.selectListener = new OnTabSelectedListener(this);
119+
const that = new WeakRef(this);
120+
this.reselectListener = new OnTabReselectedListener(that);
121+
this.selectListener = new OnTabSelectedListener(that);
120122
this.nativeViewProtected.setOnNavigationItemReselectedListener(this.reselectListener);
121123
this.nativeViewProtected.setOnNavigationItemSelectedListener(this.selectListener);
122124
// Create the tabs before setting the default values for each tab

src/bottomsheet/bottomsheet.android.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,30 @@ function getId(id: string) {
1818

1919
@NativeClass
2020
class ChangeStateBottomSheet extends com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback {
21-
private owner: ViewWithBottomSheet;
22-
23-
constructor(owner: ViewWithBottomSheet) {
21+
constructor(private owner: WeakRef<ViewWithBottomSheet>) {
2422
super();
25-
this.owner = owner;
2623
return global.__native(this);
2724
}
2825

2926
onSlide(bottomSheet: android.view.View, slideOffset: number) {
30-
if (this.checkActiveCallback()) {
31-
this.owner._onChangeStateBottomSheetCallback(StateBottomSheet.DRAGGING, slideOffset);
27+
const owner = this.owner?.get();
28+
if (owner && this.checkActiveCallback()) {
29+
owner._onChangeStateBottomSheetCallback(StateBottomSheet.DRAGGING, slideOffset);
3230
}
3331
}
3432

3533
onStateChanged(bottomSheet: android.view.View, newState: number) {
36-
if (this.checkActiveCallback()) {
34+
const owner = this.owner?.get();
35+
if (owner && this.checkActiveCallback()) {
3736
const status = this.getStateBottomSheetFromBottomSheetBehavior(newState);
3837
if (status !== undefined) {
39-
this.owner._onChangeStateBottomSheetCallback(status);
38+
owner._onChangeStateBottomSheetCallback(status);
4039
}
4140
}
4241
}
4342

4443
private checkActiveCallback() {
45-
return this.owner && this.owner._onChangeStateBottomSheetCallback;
44+
return this.owner?.get()?._onChangeStateBottomSheetCallback;
4645
}
4746

4847
public getStateBottomSheetFromBottomSheetBehavior(state: number): StateBottomSheet | undefined {
@@ -77,7 +76,7 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
7776

7877
protected _showNativeBottomSheet(parent: View, options: BottomSheetOptions) {
7978
this._commonShowNativeBottomSheet(parent, options);
80-
const owner = this;
79+
const that = new WeakRef(this);
8180
const domId = this._domId;
8281
const bottomSheetOptions: BottomSheetDataOptions = {
8382
owner: this,
@@ -100,7 +99,7 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
10099
if (bottomSheetOptions.options && bottomSheetOptions.options.dismissOnBackButton === false) {
101100
return true;
102101
}
103-
102+
const owner = that?.get();
104103
if (!owner) {
105104
return false;
106105
}
@@ -145,13 +144,21 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
145144
container: android.view.ViewGroup,
146145
savedInstanceState: android.os.Bundle
147146
): android.view.View {
148-
owner._setupAsRootView(fragment.getActivity());
149-
owner.parent = Application.getRootView();
150-
owner._isAddedToNativeVisualTree = true;
151-
return owner.nativeViewProtected;
147+
const owner = that?.get();
148+
if (owner) {
149+
owner._setupAsRootView(fragment.getActivity());
150+
owner.parent = Application.getRootView();
151+
owner._isAddedToNativeVisualTree = true;
152+
return owner.nativeViewProtected;
153+
}
154+
return null;
152155
},
153156

154157
onStart(fragment: com.nativescript.material.bottomsheet.BottomSheetDialogFragment): void {
158+
const owner = that?.get();
159+
if (!owner) {
160+
return;
161+
}
155162
const contentViewId = getId('design_bottom_sheet');
156163
const view = fragment.getDialog().findViewById(contentViewId);
157164
const transparent = bottomSheetOptions.options?.transparent === true;
@@ -195,9 +202,9 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
195202

196203
const onChangeState = bottomSheetOptions.options?.onChangeState;
197204
if (onChangeState) {
198-
const changeStateBottomSheet = new ChangeStateBottomSheet(owner);
205+
const changeStateBottomSheet = new ChangeStateBottomSheet(that);
199206
behavior.addBottomSheetCallback(changeStateBottomSheet);
200-
owner._onChangeStateBottomSheetCallback(changeStateBottomSheet.getStateBottomSheetFromBottomSheetBehavior(behavior.getState()));
207+
that?.get()?._onChangeStateBottomSheetCallback(changeStateBottomSheet.getStateBottomSheetFromBottomSheetBehavior(behavior.getState()));
201208
}
202209

203210
if (owner && !owner.isLoaded) {
@@ -224,6 +231,7 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
224231
},
225232

226233
onDismiss(fragment: com.nativescript.material.bottomsheet.BottomSheetDialogFragment, dialog: android.content.DialogInterface): void {
234+
const owner = that?.get();
227235
if (owner) {
228236
owner._bottomSheetCloseIgnore = true;
229237
}
@@ -232,6 +240,7 @@ export class ViewWithBottomSheet extends ViewWithBottomSheetBase {
232240

233241
onDestroy(fragment: com.nativescript.material.bottomsheet.BottomSheetDialogFragment): void {
234242
(df as any).nListener = null;
243+
const owner = that?.get();
235244
if (owner) {
236245
owner._bottomSheetCloseIgnore = false;
237246
owner._bottomSheetClosed();

src/slider/slider.android.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ export class Slider extends View {
8585
initNativeView() {
8686
super.initNativeView();
8787
const nativeView = this.nativeViewProtected;
88+
const that = new WeakRef(this);
8889
this.listener = new com.google.android.material.slider.Slider.OnChangeListener({
8990
onValueChange: (param0: any, value: number, fromUser: boolean) => {
90-
if (fromUser) {
91-
valueProperty.nativeValueChange(this as any, value);
91+
const owner = that?.get();
92+
if (owner && fromUser) {
93+
valueProperty.nativeValueChange(owner, value);
9294
}
9395
}
9496
});
@@ -113,8 +115,6 @@ export class Slider extends View {
113115
if (!this.trackBackgroundColor) {
114116
this.trackBackgroundColor = null;
115117
this[trackBackgroundColorProperty.setNative](null);
116-
// } else {
117-
// this[trackBackgroundColorProperty.setNative](this.trackBackgroundColor);
118118
}
119119
}
120120

src/snackbar/snackbar.android.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,22 @@ export class SnackBar extends SnackBarBase {
131131
tv.setLayoutDirection(android.view.View.LAYOUT_DIRECTION_RTL);
132132
}
133133
if (resolve) {
134+
const that = new WeakRef(this);
134135
const listener = new android.view.View.OnClickListener({
135136
onClick: (args) => {
136137
resolve({
137138
command: SnackBarAction.ACTION,
138139
reason: _getReason(1),
139140
event: args
140141
});
141-
if (this._snackbarCallback) {
142-
this._snackbarCallback.cb = null;
143-
this._snackbarCallback = null;
142+
const owner = that?.get();
143+
if (owner) {
144+
if (owner._snackbarCallback) {
145+
owner._snackbarCallback.cb = null;
146+
owner._snackbarCallback = null;
147+
}
148+
owner._snackbar = null;
144149
}
145-
this._snackbar = null;
146150
}
147151
});
148152

0 commit comments

Comments
 (0)