1.make interpolator global to avoid memleak and reduce memory usage;2.fix rippledrawable's crash and memleak

This commit is contained in:
houzh 2024-03-01 10:33:18 +08:00
parent 7a0fe215e0
commit ba48743e13
21 changed files with 64 additions and 60 deletions

View File

@ -58,7 +58,6 @@ Animation::Animation(Context* context, const AttributeSet& attrs){
}
Animation::~Animation(){
delete mInterpolator;
}
float Animation::getPivotType(const std::string&v,int &type){
@ -124,7 +123,6 @@ void Animation::setInterpolator(Context* context,const std::string&resID) {
}
void Animation::setInterpolator(Interpolator* i) {
delete mInterpolator;
mInterpolator = i;
}

View File

@ -40,14 +40,14 @@ private:
public:
static constexpr long DURATION_INFINITE = -1;
class AnimatorListener:public EventSet{
class AnimatorListener:virtual public EventSet{
public:
CallbackBase<void,Animator& /*animation*/, bool/*isReverse*/>onAnimationStart;
CallbackBase<void,Animator& /*animation*/, bool/*isReverse*/>onAnimationEnd;
CallbackBase<void,Animator& /*animation*/>onAnimationCancel;
CallbackBase<void,Animator& /*animation*/>onAnimationRepeat;
};
class AnimatorPauseListener:public EventSet{
class AnimatorPauseListener:virtual public EventSet{
public:
CallbackBase<void,Animator&> onAnimationPause;
CallbackBase<void,Animator&> onAnimationResume;

View File

@ -375,4 +375,13 @@ FastOutLinearInInterpolator::FastOutLinearInInterpolator()
:LookupTableInterpolator(VALUES3,sizeof(VALUES3)/sizeof(float)){
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
const NeverDestroyed<LinearInterpolator>LinearInterpolator::gLinearInterpolator;
const NeverDestroyed<DecelerateInterpolator>DecelerateInterpolator::gDecelerateInterpolator(1.f);
const NeverDestroyed<FastOutSlowInInterpolator>FastOutSlowInInterpolator::gFastOutSlowInInterpolator;
const NeverDestroyed<LinearOutSlowInInterpolator>LinearOutSlowInInterpolator::gLinearOutSlowInInterpolator;
const NeverDestroyed<FastOutLinearInInterpolator>FastOutLinearInInterpolator::gFastOutLinearInInterpolator;
const NeverDestroyed<AccelerateInterpolator>AccelerateInterpolator::gAccelerateInterpolator(1.f);
const NeverDestroyed<AccelerateDecelerateInterpolator>AccelerateDecelerateInterpolator::gAccelerateDecelerateInterpolator;
}//endof namespace

View File

@ -3,9 +3,10 @@
#include <math.h>
#include <vector>
#include <core/attributeset.h>
#include <core/neverdestroyed.h>
namespace cdroid{
class Context;
class TimeInterpolator{
public:
virtual float getInterpolation(float input)=0;
@ -26,6 +27,7 @@ public:
class LinearInterpolator:public BaseInterpolator{
public:
static const NeverDestroyed<LinearInterpolator>gLinearInterpolator;
float getInterpolation(float input){return input;}
};
@ -34,6 +36,7 @@ private:
float mFactor;
double mDoubleFactor;
public:
static const NeverDestroyed<AccelerateInterpolator>gAccelerateInterpolator;
AccelerateInterpolator(Context*ctx,const AttributeSet&);
AccelerateInterpolator(double f=1.);
float getInterpolation(float input)override;
@ -43,6 +46,7 @@ class DecelerateInterpolator:public BaseInterpolator{
private:
float mFactor;
public:
static const NeverDestroyed<DecelerateInterpolator>gDecelerateInterpolator;
DecelerateInterpolator(Context*ctx,const AttributeSet&);
DecelerateInterpolator(float factor=1.0);
float getInterpolation(float input)override;
@ -100,6 +104,7 @@ public:
class AccelerateDecelerateInterpolator:public BaseInterpolator{
public:
static const NeverDestroyed<AccelerateDecelerateInterpolator>gAccelerateDecelerateInterpolator;
float getInterpolation(float input)override;
};
@ -135,16 +140,19 @@ public:
class FastOutSlowInInterpolator :public LookupTableInterpolator{
public:
static const NeverDestroyed<FastOutSlowInInterpolator>gFastOutSlowInInterpolator;
FastOutSlowInInterpolator();
};
class LinearOutSlowInInterpolator:public LookupTableInterpolator{
public:
static const NeverDestroyed<LinearOutSlowInInterpolator>gLinearOutSlowInInterpolator;
LinearOutSlowInInterpolator();
};
class FastOutLinearInInterpolator:public LookupTableInterpolator{
public:
static const NeverDestroyed<FastOutLinearInInterpolator>gFastOutLinearInInterpolator;
FastOutLinearInInterpolator();
};
}//namespace

View File

@ -4,8 +4,8 @@
namespace cdroid{
TimeInterpolator* LayoutTransition::ACCEL_DECEL_INTERPOLATOR = new AccelerateDecelerateInterpolator();
TimeInterpolator* LayoutTransition::DECEL_INTERPOLATOR = new DecelerateInterpolator();
TimeInterpolator* LayoutTransition::ACCEL_DECEL_INTERPOLATOR = AccelerateDecelerateInterpolator::gAccelerateDecelerateInterpolator.get();
TimeInterpolator* LayoutTransition::DECEL_INTERPOLATOR = DecelerateInterpolator::gDecelerateInterpolator.get();
TimeInterpolator* LayoutTransition::sAppearingInterpolator = ACCEL_DECEL_INTERPOLATOR;
TimeInterpolator* LayoutTransition::sDisappearingInterpolator = ACCEL_DECEL_INTERPOLATOR;
TimeInterpolator* LayoutTransition::sChangingAppearingInterpolator = DECEL_INTERPOLATOR;

View File

@ -68,7 +68,7 @@ ValueAnimator::~ValueAnimator(){
delete v;
mValues.clear();
removeAnimationCallback();
if(mInterpolator!=sDefaultInterpolator)delete mInterpolator;
//if(mInterpolator!=sDefaultInterpolator)delete mInterpolator;
}
void ValueAnimator::setDurationScale(float durationScale) {

View File

@ -304,7 +304,7 @@ float AnimatedStateListDrawable::FrameInterpolator::getInterpolation(float input
//----------------------------------------------------------------------------------------------------------
AnimatedStateListDrawable::AnimatableTransition::AnimatableTransition(Animatable* a) {
mA = a;
mDrawable = dynamic_cast<Drawable*>(mA);
mDrawable = dynamic_cast<Drawable*>(mA);
}
void AnimatedStateListDrawable::AnimatableTransition::start() {
@ -317,17 +317,17 @@ void AnimatedStateListDrawable::AnimatableTransition::stop() {
/***************************/
AnimatedStateListDrawable::AnimationDrawableTransition::AnimationDrawableTransition(AnimationDrawable* ad, bool reversed, bool hasReversibleFlag){
const int frameCount = ad->getNumberOfFrames();
const int fromFrame = reversed ? frameCount - 1 : 0;
const int toFrame = reversed ? 0 : frameCount - 1;
FrameInterpolator* interp = new FrameInterpolator(ad, reversed);
ObjectAnimator* anim = ObjectAnimator::ofInt(ad, "currentIndex",{fromFrame, toFrame});
anim->setAutoCancel(true);
anim->setDuration(interp->getTotalDuration());
anim->setInterpolator(interp);
mHasReversibleFlag = hasReversibleFlag;
mAnim = anim;
mDrawable = ad;
const int frameCount = ad->getNumberOfFrames();
const int fromFrame = reversed ? frameCount - 1 : 0;
const int toFrame = reversed ? 0 : frameCount - 1;
FrameInterpolator* interp = new FrameInterpolator(ad, reversed);
ObjectAnimator* anim = ObjectAnimator::ofInt(ad, "currentIndex",{fromFrame, toFrame});
anim->setAutoCancel(true);
anim->setDuration(interp->getTotalDuration());
anim->setInterpolator(interp);
mHasReversibleFlag = hasReversibleFlag;
mAnim = anim;
mDrawable = ad;
}
bool AnimatedStateListDrawable::AnimationDrawableTransition::canReverse() {
@ -349,7 +349,7 @@ void AnimatedStateListDrawable::AnimationDrawableTransition::stop() {
/***************************/
AnimatedStateListDrawable::AnimatedVectorDrawableTransition::AnimatedVectorDrawableTransition(AnimatedVectorDrawable* avd,bool reversed, bool hasReversibleFlag){
mAvd = avd;
mDrawable = mAvd;
mDrawable = mAvd;
mReversed = reversed;
mHasReversibleFlag = hasReversibleFlag;
}

View File

@ -88,7 +88,7 @@ void RippleBackground::onStateChanged(){
}
mAnimator = ValueAnimator::ofFloat({mOpacity,newOpacity});//this, OPACITY, newOpacity);
mAnimator->setDuration(OPACITY_DURATION);
mAnimator->setInterpolator(new LinearInterpolator());//LINEAR_INTERPOLATOR);
mAnimator->setInterpolator(LinearInterpolator::gLinearInterpolator.get());
mAnimator->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){
PropertyValuesHolder*fp=anim.getValues(0);
mOpacity = GET_VARIANT(fp->getAnimatedValue(),float);

View File

@ -342,21 +342,14 @@ void RippleDrawable::invalidateSelf(bool invalidateMask) {
}
void RippleDrawable::pruneRipples() {
int remaining = 0;
// Move remaining entries into pruned spaces.
const int count = mExitingRipples.size();
for (int i = 0; i < count; i++) {
if (!mExitingRipples[i]->hasFinishedExit()) {
mExitingRipples[remaining++] = mExitingRipples[i];
for(auto it = mExitingRipples.begin();it!=mExitingRipples.end();it++){
RippleForeground*fg = *it;
if(fg->hasFinishedExit()){
it = mExitingRipples.erase(it);
delete fg;
if(it==mExitingRipples.end())break;
}
}
// Null out the remaining entries.
for (int i = remaining; i < count; i++) {
delete mExitingRipples[i];
}
mExitingRipples.resize(remaining);
}
int RippleDrawable::getMaskType(){

View File

@ -38,6 +38,7 @@ void RippleForeground::onTargetRadiusChanged(float targetRadius){
for (auto animator:mRunningSwAnimators) {
animator->removeListener(mAnimationListener);
animator->end();
delete animator;
}
mRunningSwAnimators.clear();
invalidateSelf();//switchToUiThreadAnimation();
@ -60,6 +61,7 @@ void RippleForeground::pruneSwFinished() {
Animator*anim=mRunningSwAnimators[i];
if (!anim->isRunning()) {
mRunningSwAnimators.erase(mRunningSwAnimators.begin()+i);
delete anim;
}
}
}
@ -101,7 +103,7 @@ void RippleForeground::startSoftwareEnter() {
mRunningSwAnimators.clear();
ValueAnimator* tweenRadius = ValueAnimator::ofFloat({.0f,1.f});//this, TWEEN_RADIUS, 1);
tweenRadius->setDuration(RIPPLE_ENTER_DURATION);
tweenRadius->setInterpolator(new DecelerateInterpolator());//DECELERATE_INTERPOLATOR);
tweenRadius->setInterpolator(DecelerateInterpolator::gDecelerateInterpolator.get());//DECELERATE_INTERPOLATOR);
tweenRadius->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){
LOGV("mTweenRadius=%f [%f,%f,%f] opacity=%f",getCurrentRadius(),mStartRadius,mTargetRadius,mOpacity);
mTweenRadius = GET_VARIANT(anim.getAnimatedValue(),float);
@ -112,7 +114,7 @@ void RippleForeground::startSoftwareEnter() {
ValueAnimator* tweenOrigin = ValueAnimator::ofFloat({.0f,1.f});//this, TWEEN_ORIGIN, 1);
tweenOrigin->setDuration(RIPPLE_ORIGIN_DURATION);
tweenOrigin->setInterpolator(new DecelerateInterpolator());//DECELERATE_INTERPOLATOR);
tweenOrigin->setInterpolator(DecelerateInterpolator::gDecelerateInterpolator.get());//DECELERATE_INTERPOLATOR);
tweenOrigin->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){
mTweenX=mTweenY=GET_VARIANT(anim.getAnimatedValue(),float);
onAnimationPropertyChanged();
@ -122,7 +124,7 @@ void RippleForeground::startSoftwareEnter() {
ValueAnimator* opacity = ValueAnimator::ofFloat({.0f,1.f});//this, OPACITY, 1);
opacity->setDuration(OPACITY_ENTER_DURATION);
opacity->setInterpolator(new LinearInterpolator());//LINEAR_INTERPOLATOR);
opacity->setInterpolator(LinearInterpolator::gLinearInterpolator.get());//LINEAR_INTERPOLATOR);
opacity->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){
mOpacity=GET_VARIANT(anim.getAnimatedValue(),float);
onAnimationPropertyChanged();
@ -134,7 +136,7 @@ void RippleForeground::startSoftwareEnter() {
void RippleForeground::startSoftwareExit() {
ValueAnimator* opacity = ValueAnimator::ofFloat({.0f,1.f});
opacity->setDuration(OPACITY_EXIT_DURATION);
opacity->setInterpolator(new LinearInterpolator());//LINEAR_INTERPOLATOR);
opacity->setInterpolator(LinearInterpolator::gLinearInterpolator.get());//LINEAR_INTERPOLATOR);
opacity->addListener(mAnimationListener);
opacity->setStartDelay(computeFadeOutDelay());
opacity->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){

View File

@ -9,7 +9,6 @@
namespace cdroid {
static NeverDestroyed<LinearInterpolator> sLinearInterpolator;
AbsListView::AbsListView(int w,int h):AdapterView(w,h) {
AttributeSet atts=mContext->obtainStyledAttributes("cdroid:attr/absListViewStyle");
initAbsListView(atts);
@ -4073,7 +4072,7 @@ void AbsListView::FlingRunnable::edgeReached(int delta) {
void AbsListView::FlingRunnable::startScroll(int distance, int duration, bool linear, bool suppressEndFlingStateChangeCall) {
const int initialY = distance < 0 ? INT_MAX : 0;
mLastFlingY = initialY;
mScroller->setInterpolator(linear ? sLinearInterpolator.get() : nullptr);
mScroller->setInterpolator(linear ? LinearInterpolator::gLinearInterpolator.get() : nullptr);
mScroller->startScroll(0, initialY, 0, distance, duration);
mLV->mTouchMode = TOUCH_MODE_FLING;
mSuppressIdleStateChangeCall = suppressEndFlingStateChangeCall;

View File

@ -359,11 +359,10 @@ OverScroller::OverScroller(Context* context):OverScroller(context,nullptr,true){
OverScroller::OverScroller(Context* context, Interpolator* interpolator, bool flywheel) {
if (interpolator == nullptr) {
mInterpolator = new Scroller::ViscousFluidInterpolator();
mInterpolator = Scroller::gViscousFluidInterpolator.get();
} else {
mInterpolator = interpolator;
}
mOwnedInterpolator=(interpolator==nullptr);
mFlywheel = flywheel;
mScrollerX = new SplineOverScroller(context);
mScrollerY = new SplineOverScroller(context);
@ -372,19 +371,14 @@ OverScroller::OverScroller(Context* context, Interpolator* interpolator, bool fl
OverScroller::~OverScroller(){
delete mScrollerX;
delete mScrollerY;
if(mOwnedInterpolator)
delete mInterpolator;
}
void OverScroller::setInterpolator(Interpolator* interpolator) {
if((interpolator!=mInterpolator)&&mOwnedInterpolator)
delete mInterpolator;
if (interpolator == nullptr) {
mInterpolator = new Scroller::ViscousFluidInterpolator();
mInterpolator = Scroller::gViscousFluidInterpolator.get();
} else {
mInterpolator = interpolator;
}
mOwnedInterpolator=(interpolator==nullptr);
}
void OverScroller::setFriction(float friction) {

View File

@ -89,7 +89,6 @@ private:
Interpolator* mInterpolator;
bool mFlywheel;
bool mOwnedInterpolator;
public:
OverScroller(Context* context);
OverScroller(Context* context, Interpolator* interpolator, bool flywheel=true);

View File

@ -611,7 +611,7 @@ void PatternLockView::startLineEndAnimation(DotState state,
}
});*/
valueAnimator->setInterpolator(mFastOutSlowInInterpolator);
valueAnimator->setInterpolator(FastOutSlowInInterpolator::gFastOutSlowInInterpolator.get());
valueAnimator->setDuration(mPathEndAnimationDuration);
valueAnimator->start();
state.mLineAnimator = valueAnimator;

View File

@ -125,7 +125,7 @@ private:
Rect mInvalidate;
Rect mTempInvalidateRect;
Interpolator* mFastOutSlowInInterpolator;
//Interpolator* mFastOutSlowInInterpolator;
Interpolator* mLinearOutSlowInInterpolator;
private:
void initView();

View File

@ -340,7 +340,7 @@ void ProgressBar::doRefreshProgress(int id, int progress, bool fromUser,bool cal
mAnimator = ObjectAnimator::ofFloat(this,"progress",{mVisualProgress,scale});
mAnimator->setAutoCancel(true);
mAnimator->setDuration(PROGRESS_ANIM_DURATION);
mAnimator->setInterpolator(new DecelerateInterpolator());
mAnimator->setInterpolator(DecelerateInterpolator::gDecelerateInterpolator.get());
mAnimator->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim){
setVisualProgress(R::id::progress,GET_VARIANT(anim.getAnimatedValue(),float));
}));
@ -595,7 +595,7 @@ void ProgressBar::startAnimation() {
}else{
mHasAnimation = true;
if (mInterpolator == nullptr) {
mInterpolator = new LinearInterpolator();
mInterpolator = LinearInterpolator::gLinearInterpolator.get();
}
if (mTransformation == nullptr) {

View File

@ -13,6 +13,8 @@ template <typename T> int signum(T val) {
float Scroller::SPLINE_POSITION [NB_SAMPLES + 1];
float Scroller::SPLINE_TIME [NB_SAMPLES + 1];
const NeverDestroyed<Scroller::ViscousFluidInterpolator>Scroller::gViscousFluidInterpolator;
Scroller::Scroller(Context* context):Scroller(context,nullptr,true){
}
@ -31,7 +33,7 @@ Scroller::Scroller(Context* context, Interpolator* interpolator, bool flywheel)
mFinished = true;
mDurationReciprocal=1.f;
if (interpolator == nullptr) {
mInterpolator = new ViscousFluidInterpolator();
mInterpolator = gViscousFluidInterpolator.get();//new ViscousFluidInterpolator();
} else {
mInterpolator = interpolator;
}
@ -43,7 +45,6 @@ Scroller::Scroller(Context* context, Interpolator* interpolator, bool flywheel)
}
Scroller::~Scroller(){
delete mInterpolator;
}
void Scroller::sInit(){

View File

@ -2,6 +2,7 @@
#define __SCROLLER_H__
#include <animation/interpolators.h>
#include <core/context.h>
#include <core/neverdestroyed.h>
#include <math.h>
namespace cdroid{
@ -97,6 +98,7 @@ public:
public:
float getInterpolation(float input)override;
};
static const NeverDestroyed<ViscousFluidInterpolator>gViscousFluidInterpolator;
};//Scroller
}//end namespace
#endif

View File

@ -615,7 +615,7 @@ void TabLayout::animateToTab(int newPosition){
void TabLayout::ensureScrollAnimator(){
if (mScrollAnimator == nullptr) {
mScrollAnimator = new ValueAnimator();
mScrollAnimator->setInterpolator(new FastOutSlowInInterpolator());
mScrollAnimator->setInterpolator(FastOutSlowInInterpolator::gFastOutSlowInInterpolator.get());
mScrollAnimator->setDuration(ANIMATION_DURATION);
mScrollAnimator->addUpdateListener(ValueAnimator::AnimatorUpdateListener([this](ValueAnimator&anim) {
PropertyValuesHolder*ip=anim.getValues()[0];
@ -1414,7 +1414,7 @@ void TabLayout::SlidingTabStrip::animateIndicatorToPosition(int position, int du
if( mIndicatorAnimator==nullptr){
mIndicatorAnimator = new ValueAnimator();
mIndicatorAnimator->setInterpolator(new FastOutSlowInInterpolator());
mIndicatorAnimator->setInterpolator(FastOutSlowInInterpolator::gFastOutSlowInInterpolator.get());
mIndicatorAnimator->setFloatValues({.0f,1.f});
}
if (startLeft != targetLeft || startRight != targetRight) {

View File

@ -28,7 +28,7 @@ ViewDragHelper::ViewDragHelper(Context* context,ViewGroup* forParent,Callback* c
mTouchSlop = vc.getScaledTouchSlop();
mMaxVelocity = vc.getScaledMaximumFlingVelocity();
mMinVelocity = vc.getScaledMinimumFlingVelocity();
mScroller = new OverScroller(context, (VDInterpolator*)sInterpolator,true);
mScroller = new OverScroller(context, (VDInterpolator*)sInterpolator.get(),true);
mSetIdleRunnable = [this](){
setDragState(STATE_IDLE);
};

View File

@ -98,7 +98,6 @@ private:
ViewGroup* mParentView;
Runnable mSetIdleRunnable;
Interpolator* sInterpolator;
private:
ViewDragHelper(Context* context,ViewGroup* forParent,Callback* cb);
bool forceSettleCapturedViewAt(int finalLeft, int finalTop, int xvel, int yvel);