android - 為什么定義一個static ImageView會導致內存泄露?
問題描述
提示說:不要把「Do not place android context classes in static fields, this is a memory leak.」
我知道activity context 不應該被放到static fields里面因為它在app生命周期內一直存在,而且如果它通過構造函數傳遞給其他class的話,其他class也會一直不被回收。
但為什么ImageView不能是static(我發(fā)現SwipeRefreshLayout也不行)?是因為ImageView包含context?Button和TextView之類的view就沒有這種問題。
問題解答
回答1:在Activity中填充布局,可以通過如下方式:
1.view view = View.inflate(context, R.layout.test,null );2.View view = LayoutInflater.from(context).inflate(R.layout.test,null);
可以發(fā)現,無論哪種方式,填充后的View都是持有context的引用的,也就是Activity的引用.如果此時填充的view是static修飾,那么靜態(tài)的對象將持續(xù)持有Activity的引用,導致Activity無法銷毀,Activity中所有的控件也都將無法徹底銷毀和回收.最終造成內存泄露.
PS:為什么要使用靜態(tài)View的方式?有什么特殊的業(yè)務需求?
回答2:static變量在內存中是單獨存在于內存塊中的,控件(你的問題中指的是ImageView)是持有Activity的引用的,這種情況下,Activity是沒法被徹底銷毀的,因為在內存中一直有一個引用(指針理解),導致Activity也無法被回收,自然就會內存泄漏了!建議,在Android中不要使用static修飾控件!
回答3:View需要持有Context (否則無法實現 setXXX(int resid)類的功能)
我也不知道Button/TextView為什么不警告
回答4:static變量無法被自動回收啊你將某個view設為靜態(tài)量,而view又持有activity的引用,這下連activity也泄露了
回答5:IPC說: static對于Android四大組件來說, 簡直就是大殺器
回答6:因為static的生命周期很長比當前activity長
回答7:這么說吧,這是java基礎.靜態(tài)變量在類文件編譯成字節(jié)碼后,載入方法區(qū)的時候,就會初始化靜態(tài)變量,而且靜態(tài)變量會一直存在,而沒有static修飾的activity,會在new的時候,在堆中申請空間,當activity沒用的時候,gc會按照gc-root遍歷此activity有沒有被引用,由于activity的context被持有,ImageView view = LayoutInflater.from(context).inflate(R.layout.test,null);,所以,gc不能回收,造成內存泄漏,,當直到虛擬機結束進程(也就是app停止),
相關文章:
1. 大兄弟們,你們都用什么框架開發(fā) web app2. mysql - 電商如何存儲營業(yè)額數據3. css - PC端不同分辨率下字體大小呈現4. css如何實現兩欄布局,左邊固定寬度,右邊寬度自適應,且高度和瀏覽器當前高度一致?5. javascript - 表單ajax提交后跳轉,手機按返回又進入這個表單頁了!!6. javascript - sublime快鍵鍵問題7. javascript - avalon使用:duplex設置select默認option的bug8. javascript - 有適合開發(fā)手機端Html5網頁小游戲的前端框架嗎?9. css3 - css做動畫效果10. HTML5禁止img預覽該怎么解決?
