diff --git a/src/gui/animation/animationhandler.cc b/src/gui/animation/animationhandler.cc index 919d60d2..6947dc62 100755 --- a/src/gui/animation/animationhandler.cc +++ b/src/gui/animation/animationhandler.cc @@ -29,6 +29,7 @@ void AnimationHandler::MyFrameCallbackProvider::setFrameDelay(long delay) { AnimationHandler::AnimationHandler(){ mProvider = nullptr; mListDirty = false; + mInLooper = false; mFrameCallback=std::bind(&AnimationHandler::doFrame,this,std::placeholders::_1); } @@ -71,8 +72,8 @@ void AnimationHandler::doAnimationFrame(long frameTime){ } bool AnimationHandler::isCallbackDue(AnimationFrameCallback* callback, long currentTime){ - auto it=mDelayedCallbackStartTime.find(callback); - if(it==mDelayedCallbackStartTime.end())return true; + auto it = mDelayedCallbackStartTime.find(callback); + if(it == mDelayedCallbackStartTime.end())return true; if (it->second < currentTime) { mDelayedCallbackStartTime.erase(it); return true; @@ -81,9 +82,9 @@ bool AnimationHandler::isCallbackDue(AnimationFrameCallback* callback, long curr } void AnimationHandler::commitAnimationFrame(AnimationFrameCallback* callback, long frameTime){ - auto it=mDelayedCallbackStartTime.find(callback); - auto itc=std::find(mCommitCallbacks.begin(),mCommitCallbacks.end(),callback); - if (it==mDelayedCallbackStartTime.end() && itc!=mCommitCallbacks.end()) { + auto it = mDelayedCallbackStartTime.find(callback); + auto itc = std::find(mCommitCallbacks.begin(),mCommitCallbacks.end(),callback); + if (it == mDelayedCallbackStartTime.end() && itc!=mCommitCallbacks.end()) { callback->commitAnimationFrame(frameTime);/*commitAnimationFrame mybe call removeCallback!!!*/ mCommitCallbacks.erase(itc); } @@ -102,6 +103,10 @@ void AnimationHandler::cleanUpList(){ static NeverDestroyedmInst; AnimationHandler&AnimationHandler::getInstance(){ + if(!mInst->mInLooper){ + Looper::getDefault()->addEventHandler(mInst.get()); + mInst->mInLooper = true; + } return *mInst; } diff --git a/src/gui/animation/animationhandler.h b/src/gui/animation/animationhandler.h index 1d25e352..e7c917ca 100755 --- a/src/gui/animation/animationhandler.h +++ b/src/gui/animation/animationhandler.h @@ -32,6 +32,7 @@ private: void setFrameDelay(long delay)override; }; bool mListDirty; + bool mInLooper; AnimationFrameCallbackProvider* mProvider; Choreographer::FrameCallback mFrameCallback; std::list mAnimationCallbacks; diff --git a/src/gui/core/looper.cc b/src/gui/core/looper.cc index 4a504a2f..47a84eee 100755 --- a/src/gui/core/looper.cc +++ b/src/gui/core/looper.cc @@ -320,11 +320,19 @@ int Looper::pollInner(int timeoutMillis) { EventHandler*es=(*it); if(es&&((es->mFlags&1)==0)&&(es->checkEvents()>0)){ es->handleEvents(); - if(es->mFlags&1) it = mEventHandlers.erase(it); - if((es->mFlags&3)==3) delete es;//EventHandler owned by looper must be freed here + //may be EventHandler::handleEvents will destroy itself,recheck the flags + if((es->mFlags&1)==1) it = mEventHandlers.erase(it); + if((es->mFlags&3)==3) delete es;//make EventHandler::handleEvents can destroy itself + //EventHandler owned by looper must be freed here + } + } + for(auto it=mEventHandlers.begin();it!=mEventHandlers.end();it++){ + EventHandler*es=(*it); + if((es->mFlags&3)==3){ + it = mEventHandlers.erase(it); + delete es;//EventHandler owned by looper must be freed here } } - //removeEventHandlers(); long elapsedMillis = SystemClock::uptimeMillis()-t1; // Acquire lock. @@ -380,7 +388,6 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat return result; } else { nsecs_t endTime = SystemClock::uptimeMillis() + timeoutMillis; - for (;;) { int result = pollOnce(timeoutMillis, outFd, outEvents, outData); if (result != POLL_CALLBACK) { @@ -621,7 +628,7 @@ void Looper::removeHandler(MessageHandler*handler){ for(auto it=mHandlers.begin();it!=mHandlers.end();it++){ if((*it)==handler){ handler->mFlags|=1; - if((handler->mFlags&2)==0)//handler is not owned by looper,erase at once + if((handler->mFlags&2)==0)//handler is not owned by looper,erase at once mHandlers.erase(it); break; } @@ -630,7 +637,6 @@ void Looper::removeHandler(MessageHandler*handler){ void Looper::addEventHandler(const EventHandler*handler){ mEventHandlers.insert(mEventHandlers.begin(),(EventHandler*)handler); - LOGE_IF(mEventHandlers.size()>32,"Too many eventhandlers %d",mEventHandlers.size()); } void Looper::removeEventHandler(const EventHandler*handler){ diff --git a/src/gui/core/uieventsource.cc b/src/gui/core/uieventsource.cc index 831ebb0f..636a5b00 100755 --- a/src/gui/core/uieventsource.cc +++ b/src/gui/core/uieventsource.cc @@ -49,7 +49,7 @@ int UIEventSource::handleRunnables(){ RUNNER runner = mRunnables.front(); if(runner.time > nowms)break; mRunnables.pop_front(); - if(runner.run)runner.run(); + if(runner.run&&(runner.removed==false))runner.run(); count++; } if(((mFlags&1)==0) && mAttachedView->isDirty() && mAttachedView->getVisibility()==View::VISIBLE){ diff --git a/src/gui/view/view.cc b/src/gui/view/view.cc index a9387288..649ccc0d 100755 --- a/src/gui/view/view.cc +++ b/src/gui/view/view.cc @@ -381,11 +381,6 @@ View::~View(){ mViewCount --; LOGD_IF(View::VIEW_DEBUG||(mViewCount>1000),"%p:%d mViewCount=%d",this,mID,mViewCount); - removeTapCallback(); - removeLongPressCallback(); - removePerformClickCallback(); - removeUnsetPressCallback(); - delete mScrollCache; mScrollCache = nullptr; if(mParent) @@ -1411,6 +1406,7 @@ void View::onDetachedFromWindowInternal() { mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT; mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH; + removeTapCallback(); removeUnsetPressCallback(); removeLongPressCallback(); removePerformClickCallback(); diff --git a/src/gui/widget/abslistview.cc b/src/gui/widget/abslistview.cc index 63fda809..98bbc6aa 100755 --- a/src/gui/widget/abslistview.cc +++ b/src/gui/widget/abslistview.cc @@ -118,12 +118,6 @@ AbsListView::~AbsListView() { mVelocityTracker->recycle(); mVelocityTracker = nullptr; } - if(mPerformClick)mPerformClick->removeCallbacks(); - if(mPendingCheckForLongPress)mPendingCheckForLongPress->removeCallbacks(); - if(mPendingCheckForTap)mPendingCheckForTap->removeCallbacks(); - if(mPendingCheckForKeyLongPress)mPendingCheckForKeyLongPress->removeCallbacks(); - if(mFlingRunnable)mFlingRunnable->removeCallbacks(); - delete mSelector; delete mFastScroll; delete mRecycler; @@ -1942,6 +1936,11 @@ void AbsListView::onAttachedToWindow() { void AbsListView::onDetachedFromWindow() { AdapterView::onDetachedFromWindow(); + if(mPerformClick)mPerformClick->removeCallbacks(); + if(mPendingCheckForLongPress)mPendingCheckForLongPress->removeCallbacks(); + if(mPendingCheckForTap)mPendingCheckForTap->removeCallbacks(); + if(mPendingCheckForKeyLongPress)mPendingCheckForKeyLongPress->removeCallbacks(); + if(mFlingRunnable)mFlingRunnable->removeCallbacks(); mIsDetaching = true; // Dismiss the popup in case onSaveInstanceState() was not invoked