mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-14 18:12:09 +08:00
fix(android): FragmentClass memory leak (#9983)
* chore: resilience to create/destroy flow around actionItems Co-authored-by: Nathan Walker <walkerrunpdx@gmail.com>
This commit is contained in:
@ -25,6 +25,10 @@ export class ActionBarBase extends View implements ActionBarDefinition {
|
|||||||
get navigationButton(): NavigationButton {
|
get navigationButton(): NavigationButton {
|
||||||
return this._navigationButton;
|
return this._navigationButton;
|
||||||
}
|
}
|
||||||
|
disposeNativeView() {
|
||||||
|
this._actionItems = null;
|
||||||
|
super.disposeNativeView();
|
||||||
|
}
|
||||||
set navigationButton(value: NavigationButton) {
|
set navigationButton(value: NavigationButton) {
|
||||||
if (this._navigationButton !== value) {
|
if (this._navigationButton !== value) {
|
||||||
if (this._navigationButton) {
|
if (this._navigationButton) {
|
||||||
@ -114,7 +118,7 @@ export class ActionBarBase extends View implements ActionBarDefinition {
|
|||||||
|
|
||||||
get _childrenCount(): number {
|
get _childrenCount(): number {
|
||||||
let actionViewsCount = 0;
|
let actionViewsCount = 0;
|
||||||
this._actionItems.getItems().forEach((actionItem) => {
|
this._actionItems?.getItems().forEach((actionItem) => {
|
||||||
if (actionItem.actionView) {
|
if (actionItem.actionView) {
|
||||||
actionViewsCount++;
|
actionViewsCount++;
|
||||||
}
|
}
|
||||||
@ -140,7 +144,7 @@ export class ActionBarBase extends View implements ActionBarDefinition {
|
|||||||
|
|
||||||
public _addArrayFromBuilder(name: string, value: Array<any>) {
|
public _addArrayFromBuilder(name: string, value: Array<any>) {
|
||||||
if (name === 'actionItems') {
|
if (name === 'actionItems') {
|
||||||
this.actionItems.setItems(value);
|
this.actionItems?.setItems(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,13 +166,13 @@ export class ActionBarBase extends View implements ActionBarDefinition {
|
|||||||
callback(navigationButton);
|
callback(navigationButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionItems.getItems().forEach((actionItem) => {
|
this.actionItems?.getItems().forEach((actionItem) => {
|
||||||
callback(actionItem);
|
callback(actionItem);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public _isEmpty(): boolean {
|
public _isEmpty(): boolean {
|
||||||
if (this.title || this.titleView || (this.android && this.android.icon) || this.navigationButton || this.actionItems.getItems().length > 0) {
|
if (this.title || this.titleView || (this.android && this.android.icon) || this.navigationButton || this.actionItems?.getItems().length > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
if (value instanceof NavigationButton) {
|
if (value instanceof NavigationButton) {
|
||||||
this.navigationButton = value;
|
this.navigationButton = value;
|
||||||
} else if (value instanceof ActionItem) {
|
} else if (value instanceof ActionItem) {
|
||||||
this.actionItems.addItem(value);
|
this.actionItems?.addItem(value);
|
||||||
} else if (value instanceof View) {
|
} else if (value instanceof View) {
|
||||||
this.titleView = value;
|
this.titleView = value;
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
|
|
||||||
// Find item with the right ID;
|
// Find item with the right ID;
|
||||||
let menuItem: ActionItem = undefined;
|
let menuItem: ActionItem = undefined;
|
||||||
const items = this.actionItems.getItems();
|
const items = this.actionItems?.getItems() ?? [];
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
if ((<ActionItem>items[i])._getItemId() === itemId) {
|
if ((<ActionItem>items[i])._getItemId() === itemId) {
|
||||||
menuItem = <ActionItem>items[i];
|
menuItem = <ActionItem>items[i];
|
||||||
@ -352,7 +352,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
|
|
||||||
public _addActionItems() {
|
public _addActionItems() {
|
||||||
const menu = this.nativeViewProtected.getMenu();
|
const menu = this.nativeViewProtected.getMenu();
|
||||||
const items = this.actionItems.getVisibleItems();
|
const items = this.actionItems?.getVisibleItems() ?? [];
|
||||||
|
|
||||||
menu.clear();
|
menu.clear();
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
@ -148,7 +148,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
if (value instanceof NavigationButton) {
|
if (value instanceof NavigationButton) {
|
||||||
this.navigationButton = value;
|
this.navigationButton = value;
|
||||||
} else if (value instanceof ActionItem) {
|
} else if (value instanceof ActionItem) {
|
||||||
this.actionItems.addItem(value);
|
this.actionItems?.addItem(value);
|
||||||
} else if (value instanceof View) {
|
} else if (value instanceof View) {
|
||||||
this.titleView = value;
|
this.titleView = value;
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private populateMenuItems(navigationItem: UINavigationItem) {
|
private populateMenuItems(navigationItem: UINavigationItem) {
|
||||||
const items = this.actionItems.getVisibleItems();
|
const items = this.actionItems?.getVisibleItems() ?? [];
|
||||||
const leftBarItems = NSMutableArray.new();
|
const leftBarItems = NSMutableArray.new();
|
||||||
const rightBarItems = NSMutableArray.new();
|
const rightBarItems = NSMutableArray.new();
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
@ -449,7 +449,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
View.measureChild(this, this.titleView, UNSPECIFIED, UNSPECIFIED);
|
View.measureChild(this, this.titleView, UNSPECIFIED, UNSPECIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionItems.getItems().forEach((actionItem) => {
|
this.actionItems?.getItems().forEach((actionItem) => {
|
||||||
const actionView = actionItem.actionView;
|
const actionView = actionItem.actionView;
|
||||||
if (actionView) {
|
if (actionView) {
|
||||||
View.measureChild(this, actionView, UNSPECIFIED, UNSPECIFIED);
|
View.measureChild(this, actionView, UNSPECIFIED, UNSPECIFIED);
|
||||||
@ -473,7 +473,7 @@ export class ActionBar extends ActionBarBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionItems.getItems().forEach((actionItem) => {
|
this.actionItems?.getItems().forEach((actionItem) => {
|
||||||
const actionView = actionItem.actionView;
|
const actionView = actionItem.actionView;
|
||||||
if (actionView && actionView.ios) {
|
if (actionView && actionView.ios) {
|
||||||
const measuredWidth = actionView.getMeasuredWidth();
|
const measuredWidth = actionView.getMeasuredWidth();
|
||||||
|
@ -324,7 +324,15 @@ export class View extends ViewCommon {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.on(View.loadedEvent, () => setupAccessibleView(this));
|
const weakRef = new WeakRef(this);
|
||||||
|
const handler = () => {
|
||||||
|
const owner = weakRef.get();
|
||||||
|
if (owner) {
|
||||||
|
setupAccessibleView(owner);
|
||||||
|
owner.off(View.loadedEvent, handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.on(View.loadedEvent, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement unobserve that detach the touchListener.
|
// TODO: Implement unobserve that detach the touchListener.
|
||||||
|
Reference in New Issue
Block a user