国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用Handler造成內存泄露的分析和解決辦法

2019-11-06 09:41:52
字體:
來源:轉載
供稿:網友

Android中使用Handler造成內存泄露的分析和解決辦法


問題描述:This Handler class should be static or leaks might occur (anonymous android.os.Handler)(參考 https://my.oschina.net/liucundong/blog/294127)

特性:當Activity被finish()掉,Message 將存在于消息隊列中長達10分鐘的時間才會被執行到。這個Message持有一個對Handler的引用,Handler也會持有一個對于外部類(SampleActivity)的隱式引用,這些引用在Message被執行前將一直保持,這樣會保證Activity的上下文不被垃圾回收機制回收,同時也會泄露應用程序的資源(views and resources)。 ADT20以后加入了一條新的檢查規則:確保類內部的handler不含有對外部類的隱式引用 。

常見寫法

PRivate Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case 0: break; default: break; } } };

上述寫法引起泄露原因是:

當Android應用啟動的時候,會先創建一個應用主線程的Looper對象,Looper實現了一個簡單的消息隊列,一個一個的處理里面的Message對象。主線程Looper對象在整個應用生命周期中存在。

當在主線程中初始化Handler時,該Handler和Looper的消息隊列關聯。發送到消息隊列的Message會引用發送該消息的Handler對象,這樣系統可以調用 Handler#handleMessage(Message) 來分發處理該消息。

java中,非靜態(匿名)內部類會引用外部類對象。而靜態內部類不會引用外部類對象。

-如果外部類是Activity,則會引起Activity泄露 。

當Activity finish后,延時消息會繼續存在主線程消息隊列中1分鐘,然后處理消息。而該消息引用了Activity的Handler對象,然后這個Handler又引用了這個Activity。這些引用對象會保持到該消息被處理完,這樣就導致該Activity對象無法被回收,從而導致了上面說的 Activity泄露。

為解決這個問題,下面這段代碼中的Handler則是一個靜態匿名內部類。靜態匿名內部類不會持有一個對外部類的隱式引用,因此Activity將不會被泄露。如果你需要在Handler中調用外部Activity的方法,就讓Handler持有一個對Activity的WeakReference,這樣就不會泄露Activity的上下文了


如下所示private final MyHandler mHandler = new MyHandler(this);static class MyHandler extends Handler { private final WeakReference<CashActivity> mActivity; public MyHandler(CashActivity activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { System.out.println(msg); if (mActivity.get() == null) { return; } CashActivity activity = mActivity.get(); switch (msg.what) { case 0: activity.submit_but.setVisibility(View.VISIBLE); break; default: break; } } }}

同時我們盡量要在當前Activity的生命周期內結束對所有回調函數和message的引用

@Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null); }

至此一個可以內存泄露的問題輕松處理,get!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿克陶县| 荥阳市| 庆安县| 锦州市| 新平| 东乌珠穆沁旗| 江永县| 高陵县| 九龙坡区| 赤城县| 南投县| 齐河县| 织金县| 南投县| 台中市| 昌吉市| 甘泉县| 县级市| 潼南县| 北川| 监利县| 江西省| 杭锦旗| 兴仁县| 灵台县| 乌拉特后旗| 迁西县| 新建县| 蛟河市| 拉孜县| 左云县| 呼伦贝尔市| 新泰市| 滁州市| 龙井市| 缙云县| 丹寨县| 广河县| 北川| 噶尔县| 九寨沟县|