modify looper& uieventsource,make self destroy more safely

This commit is contained in:
houzh 2024-02-01 11:11:32 +08:00
parent 4a69c3a3ef
commit 082339e621
6 changed files with 30 additions and 23 deletions

View File

@ -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 NeverDestroyed<AnimationHandler>mInst;
AnimationHandler&AnimationHandler::getInstance(){
if(!mInst->mInLooper){
Looper::getDefault()->addEventHandler(mInst.get());
mInst->mInLooper = true;
}
return *mInst;
}

View File

@ -32,6 +32,7 @@ private:
void setFrameDelay(long delay)override;
};
bool mListDirty;
bool mInLooper;
AnimationFrameCallbackProvider* mProvider;
Choreographer::FrameCallback mFrameCallback;
std::list<AnimationFrameCallback*> mAnimationCallbacks;

View File

@ -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) {
@ -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){

View File

@ -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){

View File

@ -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();

View File

@ -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