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