現(xiàn)象
某一天應(yīng)用出現(xiàn)bug,看日志后,發(fā)現(xiàn)activity回調(diào)onstop和ondestroy很慢,導(dǎo)致單例持有的資源未及時(shí)釋放。經(jīng)過測(cè)試,發(fā)現(xiàn)在7.0以及以上版本系統(tǒng),A界面跳轉(zhuǎn)B界面后(B可以是任何界面),點(diǎn)擊返回鍵等回到A界面,B執(zhí)行了onpause后,等了10秒B界面才會(huì)執(zhí)行onstop和ondestroy。
分析問題:
由于我是一個(gè)首頁的子fragment,所以一開始懷疑繼承項(xiàng)目的basefragment被人寫了啥,然后對(duì)比其它幾個(gè)子fragment的代碼,沒發(fā)現(xiàn)差異,然后看承載fragment的主頁activity,仍然沒有。之后注釋大數(shù)據(jù)埋點(diǎn)等一些acitivity里的耗時(shí)動(dòng)作,所有onstart和onresume方法都注釋了,仍然不行。最后把fragment的列表注釋不加載,發(fā)現(xiàn)不出現(xiàn)延遲了。然后排查數(shù)據(jù)刷新動(dòng)作以及綁定,最后開始注釋掉適配器的adapter的bind方法,ok,無bug了。然后逐步恢復(fù)代碼,最后發(fā)現(xiàn)是下面的代碼導(dǎo)致的onstop延遲10秒,最終定位到adapter里,有下面AnimationUtils代碼導(dǎo)致的。懷疑是系統(tǒng)7.0后從緩存里取出A界面的view重新繪制到界面時(shí)有什么優(yōu)化改動(dòng),然后AnimationUtils影響到了。
初步推測(cè):是A界面離開onpause后,沒有停止循環(huán)動(dòng)畫。
開始驗(yàn)證:
1.方案1在activityA里,放一個(gè)控件循環(huán)動(dòng)畫,然后啟動(dòng)B,此時(shí)再從B返回,看是否B界面等了10秒才觸發(fā)onstop
2.方案2擴(kuò)展思路驗(yàn)證,在B界面放置一個(gè)循環(huán)動(dòng)畫,然后離開界面時(shí)不停止,看是否會(huì)導(dǎo)致B界面onstop出現(xiàn)延遲10秒左右才觸發(fā)。

上圖中模擬的是1,A界面TransparencyActivity啟動(dòng)B界面MainActivity,然后16:01:10.578離開MainActivity,看日志已經(jīng)恢復(fù)TransparencyActivity。但是等到16:01:20.607才開始走onstop和ondestroy。驗(yàn)證動(dòng)畫確實(shí)影響界面銷毀成功,那么解決方案很明顯了。
模擬2發(fā)現(xiàn)一切都正常,日志如下。

解決方案
離開界面A時(shí)要停止循環(huán)動(dòng)畫,然后從B界面返回時(shí),B的生命周期才會(huì)正常。
由于離開界面A時(shí)要停止循環(huán)動(dòng)畫,所以再次從B返回A界面時(shí),需要恢復(fù)動(dòng)畫。
總結(jié)
7.0以上系統(tǒng)開啟動(dòng)畫后,在離開當(dāng)前界面onpause一定暫停動(dòng)畫,不然會(huì)影響當(dāng)前界面跳轉(zhuǎn)的下一級(jí)頁面B的銷毀,會(huì)造成B頁面離開onpause回調(diào)后,10秒后才觸發(fā)onstop和ondestroy。至于源碼目前還未探索,如果有后續(xù)查閱,會(huì)更新本文。