android - 為什么定義一個(gè)static ImageView會(huì)導(dǎo)致內(nèi)存泄露?
問(wèn)題描述
提示說(shuō):不要把「Do not place android context classes in static fields, this is a memory leak.」
我知道activity context 不應(yīng)該被放到static fields里面因?yàn)樗赼pp生命周期內(nèi)一直存在,而且如果它通過(guò)構(gòu)造函數(shù)傳遞給其他class的話,其他class也會(huì)一直不被回收。
但為什么ImageView不能是static(我發(fā)現(xiàn)SwipeRefreshLayout也不行)?是因?yàn)镮mageView包含context?Button和TextView之類的view就沒(méi)有這種問(wèn)題。
問(wèn)題解答
回答1:在Activity中填充布局,可以通過(guò)如下方式:
1.view view = View.inflate(context, R.layout.test,null );2.View view = LayoutInflater.from(context).inflate(R.layout.test,null);
可以發(fā)現(xiàn),無(wú)論哪種方式,填充后的View都是持有context的引用的,也就是Activity的引用.如果此時(shí)填充的view是static修飾,那么靜態(tài)的對(duì)象將持續(xù)持有Activity的引用,導(dǎo)致Activity無(wú)法銷毀,Activity中所有的控件也都將無(wú)法徹底銷毀和回收.最終造成內(nèi)存泄露.
PS:為什么要使用靜態(tài)View的方式?有什么特殊的業(yè)務(wù)需求?
回答2:static變量在內(nèi)存中是單獨(dú)存在于內(nèi)存塊中的,控件(你的問(wèn)題中指的是ImageView)是持有Activity的引用的,這種情況下,Activity是沒(méi)法被徹底銷毀的,因?yàn)樵趦?nèi)存中一直有一個(gè)引用(指針理解),導(dǎo)致Activity也無(wú)法被回收,自然就會(huì)內(nèi)存泄漏了!建議,在Android中不要使用static修飾控件!
回答3:View需要持有Context (否則無(wú)法實(shí)現(xiàn) setXXX(int resid)類的功能)
我也不知道Button/TextView為什么不警告
回答4:static變量無(wú)法被自動(dòng)回收啊你將某個(gè)view設(shè)為靜態(tài)量,而view又持有activity的引用,這下連activity也泄露了
回答5:IPC說(shuō): static對(duì)于Android四大組件來(lái)說(shuō), 簡(jiǎn)直就是大殺器
回答6:因?yàn)閟tatic的生命周期很長(zhǎng)比當(dāng)前activity長(zhǎng)
回答7:這么說(shuō)吧,這是java基礎(chǔ).靜態(tài)變量在類文件編譯成字節(jié)碼后,載入方法區(qū)的時(shí)候,就會(huì)初始化靜態(tài)變量,而且靜態(tài)變量會(huì)一直存在,而沒(méi)有static修飾的activity,會(huì)在new的時(shí)候,在堆中申請(qǐng)空間,當(dāng)activity沒(méi)用的時(shí)候,gc會(huì)按照gc-root遍歷此activity有沒(méi)有被引用,由于activity的context被持有,ImageView view = LayoutInflater.from(context).inflate(R.layout.test,null);,所以,gc不能回收,造成內(nèi)存泄漏,,當(dāng)直到虛擬機(jī)結(jié)束進(jìn)程(也就是app停止),
相關(guān)文章:
1. mysql - 這條聯(lián)合sql語(yǔ)句哪里錯(cuò)了2. mysql優(yōu)化 - 關(guān)于mysql分區(qū)3. 請(qǐng)教各位大佬,瀏覽器點(diǎn) 提交實(shí)例為什么沒(méi)有反應(yīng)4. java - Atom中文問(wèn)題5. java - MySQL中,使用聚合函數(shù)+for update會(huì)鎖表嗎?6. css3 - 這個(gè)形狀使用CSS怎么寫(xiě)出來(lái)?7. javascript - 為什么這個(gè)點(diǎn)擊事件需要點(diǎn)擊兩次才有效果8. node.js - 在vuejs-templates/webpack中dev-server.js里為什么要exports readyPromise?9. javascript - ionic2 input autofocus 電腦成功,iOS手機(jī)鍵盤(pán)不彈出10. java - C語(yǔ)言算法題-韓信點(diǎn)兵 求解?
