Skip to content

Commit

Permalink
fix(android-animations): reuse animatorSet to prevent high memory usa…
Browse files Browse the repository at this point in the history
…ge (#6930)
  • Loading branch information
ADjenkov committed Feb 21, 2019
1 parent 09fa085 commit 7236d32
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 19 deletions.
56 changes: 39 additions & 17 deletions tns-core-modules/ui/animation/animation.android.ts
Expand Up @@ -9,6 +9,7 @@ import {
} from "../styling/style-properties";

import { layout } from "../../utils/utils";
import { device } from "../../platform";
import lazy from "../../utils/lazy";

export * from "./animation-common";
Expand Down Expand Up @@ -92,6 +93,7 @@ export class Animation extends AnimationBase {
private _propertyResetCallbacks: Array<Function>;
private _valueSource: "animation" | "keyframe";
private _target: View;
private _resetOnFinish: boolean = true;

constructor(animationDefinitions: Array<AnimationDefinitionInternal>, playSequentially?: boolean) {
super(animationDefinitions, playSequentially);
Expand Down Expand Up @@ -134,12 +136,18 @@ export class Animation extends AnimationBase {
});
}

public play(): AnimationPromise {
public play(resetOnFinish?: boolean): AnimationPromise {
if (resetOnFinish !== undefined) {
this._resetOnFinish = resetOnFinish;
}

if (this.isPlaying) {
return this._rejectAlreadyPlaying();
}

let animationFinishedPromise = super.play();
if (this._animatorSet) {
return this._play();
}

this._animators = new Array<android.animation.Animator>();
this._propertyUpdateCallbacks = new Array<Function>();
Expand All @@ -156,21 +164,8 @@ export class Animation extends AnimationBase {

this._animatorSet = new android.animation.AnimatorSet();
this._animatorSet.addListener(this._animatorListener);
if (this._animators.length > 0) {
if (this._playSequentially) {
this._animatorSet.playSequentially(this._nativeAnimatorsArray);
}
else {
this._animatorSet.playTogether(this._nativeAnimatorsArray);
}
}

if (traceEnabled()) {
traceWrite("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), traceCategories.Animation);
}
this._animatorSet.setupStartValues();
this._animatorSet.start();
return animationFinishedPromise;
return this._play();
}

public cancel(): void {
Expand All @@ -188,6 +183,33 @@ export class Animation extends AnimationBase {
return _resolveAnimationCurve(curve);
}

private _play(): AnimationPromise {
const animationFinishedPromise = super.play();

if (device.sdkVersion <= "23") {
this._animatorSet = new android.animation.AnimatorSet();
this._animatorSet.addListener(this._animatorListener);
}

if (this._animators.length > 0) {
if (this._playSequentially) {
this._animatorSet.playSequentially(this._nativeAnimatorsArray);
}
else {
this._animatorSet.playTogether(this._nativeAnimatorsArray);
}
}

if (traceEnabled()) {
traceWrite("Starting " + this._nativeAnimatorsArray.length + " animations " + (this._playSequentially ? "sequentially." : "together."), traceCategories.Animation);
}

this._animatorSet.setupStartValues();
this._animatorSet.start();

return animationFinishedPromise;
}

private _onAndroidAnimationEnd() { // tslint:disable-line
if (!this.isPlaying) {
// It has been cancelled
Expand All @@ -197,7 +219,7 @@ export class Animation extends AnimationBase {
this._propertyUpdateCallbacks.forEach(v => v());
this._resolveAnimationFinishedPromise();

if (this._target) {
if (this._resetOnFinish && this._target) {
this._target._removeAnimation(this);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tns-core-modules/ui/animation/animation.d.ts
Expand Up @@ -126,7 +126,7 @@ export type AnimationPromise = Promise<void> & Cancelable;
*/
export class Animation {
constructor(animationDefinitions: Array<AnimationDefinition>, playSequentially?: boolean);
public play: () => AnimationPromise;
public play: (resetOnFinish?: boolean) => AnimationPromise;
public cancel: () => void;
public isPlaying: boolean;
public _resolveAnimationCurve(curve: any): any;
Expand Down
4 changes: 3 additions & 1 deletion tns-core-modules/ui/animation/keyframe-animation.ts
Expand Up @@ -243,8 +243,10 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
this._nativeAnimations.push(animation);
}

const isLastIteration = iterations - 1 <= 0;

// Catch the animation cancel to prevent unhandled promise rejection warnings
animation.play().then(() => {
animation.play(isLastIteration).then(() => {
this.animate(view, index + 1, iterations);
}, (error: any) => {
traceWrite(typeof error === "string" ? error : error.message, traceCategories.Animation, traceType.warn);
Expand Down

0 comments on commit 7236d32

Please sign in to comment.