您好,登錄后才能下訂單哦!
本篇內容主要講解“Handler引起的內存泄露怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Handler引起的內存泄露怎么解決”吧!
先看一組簡單的代碼
public class SampleActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } }
當我們這樣寫在一個Activity
中時,Android Lint
會提示我們這樣一個 warning: In Android, Handler classes should be static or leaks might occur.
。
意思說:在Android中,Handler 類應該是靜態的否則可能發生泄漏。
為什么會是這樣呢?
了解一下Handler
當Android程序***次創建的時候,在主線程同時會創建一個Looper
對象。Looper
實現了一個簡單的消息隊列,一個接著一個處理Message
對象。程序框架所有主要的事件(例如:屏幕上的點擊時間,Activity
生命周期的方法等等)都包含在Message
對象中,然后添加到Looper
的消息隊列中,一個一個處理。主線程的Looper
存在整個應用程序的生命周期內。
當一個Handler
對象在主線程中創建的時候,它會關聯到Looper
的 message queue 。Message
添加到消息隊列中的時候Message
會持有當前Handler
引用,當Looper
處理到當前消息的時候,會調用Handler#handleMessage(Message)
.
在java
中,no-static
的內部類會 隱式的 持有當前類的一個引用。static
的類則沒有。
在什么地方引起了內存的泄露呢?再看看下面一段代碼
public class SampleActivity extends Activity { private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // ... } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 發送一個10分鐘后執行的一個消息 mHandler.postDelayed(new Runnable() { @Override public void run() { } }, 600000); // 結束當前的Activity finish(); } }
當Activity
結束后,在 Message queue 處理這個Message
之前,它會持續存活著。這個Message
持有Handler
的引用,而Handler
有持有Activity
(SampleActivity)的引用,這個Activity
所有的資源,在這個消息處理之前都不能也不會被回收,所以發生了內存泄露。
解決辦法,看下面一段代碼
public class SampleActivity extends Activity { /** * 使用靜態的內部類,不會持有當前對象的引用 */ private static class MyHandler extends Handler { private final WeakReference<SampleActivity> mActivity; public MyHandler(SampleActivity activity) { mActivity = new WeakReference<SampleActivity>(activity); } @Override public void handleMessage(Message msg) { SampleActivity activity = mActivity.get(); if (activity != null) { // ... } } } private final MyHandler mHandler = new MyHandler(this); /** * 使用靜態的內部類,不會持有當前對象的引用 */ private static final Runnable sRunnable = new Runnable() { @Override public void run() { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 發送一個10分鐘后執行的一個消息 mHandler.postDelayed(sRunnable, 600000); // 結束 finish(); } }
到此,相信大家對“Handler引起的內存泄露怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。