Android 中 Handler 引起的內(nèi)存泄露_第1頁(yè)
Android 中 Handler 引起的內(nèi)存泄露_第2頁(yè)
Android 中 Handler 引起的內(nèi)存泄露_第3頁(yè)
Android 中 Handler 引起的內(nèi)存泄露_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Android 中 Handler 引起的內(nèi)存泄露在A(yíng)ndroid常用編程中,Handler在進(jìn)行異步操作并處理返回結(jié)果時(shí)經(jīng)常被使用。通常我們的代碼會(huì)這樣實(shí)現(xiàn)。1. public class SampleActivity extends Activity  2.  3.   private final Handler mLeakyHandler = new Handler()  4.    

2、60;Override 5.     public void handleMessage(Message msg)  6.       / .  7.      8.    9.  但是,其實(shí)上面的代碼可能導(dǎo)致內(nèi)存泄露,當(dāng)你使用Android lint工具的話(huà),會(huì)得到這樣的警告In Android, Handler c

3、lasses should be static or leaks might occur, Messages enqueued on the application threads MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a

4、WeakReference to its outer class看到這里,可能還是有一些搞不清楚,代碼中哪里可能導(dǎo)致內(nèi)存泄露,又是如何導(dǎo)致內(nèi)存泄露的呢?那我們就慢慢分析一下。1.當(dāng)一個(gè)Android應(yīng)用啟動(dòng)的時(shí)候,會(huì)自動(dòng)創(chuàng)建一個(gè)供應(yīng)用主線(xiàn)程使用的Looper實(shí)例。Looper的主要工作就是一個(gè)一個(gè)處理消息隊(duì)列中 的消息對(duì)象。在A(yíng)ndroid中,所有Android框架的事件(比如Activity的生命周期方法調(diào)用和按鈕點(diǎn)擊等)都是放入到消息中,然后加入到 Looper要處理的消息隊(duì)列中,由Looper負(fù)責(zé)一條一條地進(jìn)行處理。主線(xiàn)程中的Looper生命周期和當(dāng)前應(yīng)用一樣長(zhǎng)。2.當(dāng)一個(gè)Handler

5、在主線(xiàn)程進(jìn)行了初始化之后,我們發(fā)送一個(gè)target為這個(gè)Handler的消息到Looper處理的消息隊(duì)列時(shí),實(shí)際上 已經(jīng)發(fā)送的消息已經(jīng)包含了一個(gè)Handler實(shí)例的引用,只有這樣Looper在處理到這條消息時(shí)才可以調(diào)用 Handler#handleMessage(Message)完成消息的正確處理。3.在Java中,非靜態(tài)的內(nèi)部類(lèi)和匿名內(nèi)部類(lèi)都會(huì)隱式地持有其外部類(lèi)的引用。靜態(tài)的內(nèi)部類(lèi)不會(huì)持有外部類(lèi)的引用。關(guān)于這一內(nèi)容可以查看細(xì)話(huà)Java:”失效”的private修飾符確實(shí)上面的代碼示例有點(diǎn)難以察覺(jué)內(nèi)存泄露,那么下面的例子就非常明顯了1. public class Sampl

6、eActivity extends Activity  2.  3.   private final Handler mLeakyHandler = new Handler()  4.     Override 5.     public void handleMessage(Message msg)  6.

7、       / . 7.      8.    9.  10.   Override 11.   protected void onCreate(Bundle savedInstanceState)  12.     super.onCreate(savedInstanceState);

8、 13.  14.     / Post a message and delay its execution for 10 minutes. 15.     mLeakyHandler.postDelayed(new Runnable()  16.       Override 17. &

9、#160;     public void run()  /* . */  18.     , 1000 * 60 * 10); 19.  20.     / Go back to the previous Activity. 21.  &

10、#160;  finish(); 22.    23.  分析一下上面的代碼,當(dāng)我們執(zhí)行了Activity的finish方法,被延遲的消息會(huì)在被處理之前存在于主線(xiàn)程消息隊(duì)列中10分鐘,而這個(gè)消息中 又包含了Handler的引用,而Handler是一個(gè)匿名內(nèi)部類(lèi)的實(shí)例,其持有外面的SampleActivity的引用,所以這導(dǎo)致了 SampleActivity無(wú)法回收,進(jìn)行導(dǎo)致SampleActivity持有的很多資源都無(wú)法回收,這就是我們常說(shuō)的內(nèi)存泄露。注意上面的new Runnable這里也是匿名內(nèi)部類(lèi)實(shí)現(xiàn)的,同樣也會(huì)持有S

11、ampleActivity的引用,也會(huì)阻止SampleActivity被回收。要解決這種問(wèn)題,思路就是不適用非靜態(tài)內(nèi)部類(lèi),繼承Handler時(shí),要么是放在單獨(dú)的類(lèi)文件中,要么就是使用靜態(tài)內(nèi)部類(lèi)。因?yàn)殪o態(tài)的內(nèi)部類(lèi)不會(huì)持有外部類(lèi)的引用,所以不會(huì)導(dǎo)致外部類(lèi)實(shí)例的內(nèi)存泄露。當(dāng)你需要在靜態(tài)內(nèi)部類(lèi)中調(diào)用外部的Activity時(shí),我們可以使用弱引用來(lái)處理。另外關(guān)于同樣也需要將Runnable設(shè)置為靜態(tài)的成員屬性。注意:一個(gè)靜態(tài)的匿名內(nèi)部類(lèi)實(shí)例不會(huì)持有外部類(lèi)的引用。 修改后不會(huì)導(dǎo)致內(nèi)存泄露的代碼如下1. public class SampleActivity extends

12、60;Activity  2.  3.   /* 4.    * Instances of static inner classes do not hold an implicit 5.    * reference to their outer class. 6.    */&

13、#160;7.   private static class MyHandler extends Handler  8.     private final WeakReference<SampleActivity> mActivity; 9.  10.     public MyHandler(SampleActivity activity)&

14、#160; 11.       mActivity = new WeakReference<SampleActivity>(activity); 12.      13.  14.     Override 15.     public void handleMessage(Message msg

15、)  16.       SampleActivity activity = mActivity.get(); 17.       if (activity != null)  18.         / . 19.     &#

16、160;  20.      21.    22.  23.   private final MyHandler mHandler = new MyHandler(this); 24.  25.   /* 26.    * Instances of anonymous classes

17、60;do not hold an implicit 27.    * reference to their outer class when they are "static". 28.    */ 29.   private static final Runnable sRunnable

18、0;= new Runnable()  30.       Override 31.       public void run()  /* . */  32.    33.  34.   Override 35.   protected void onCreate(Bundle savedInstanceState)  36.     super.onCreate(savedInstanceState); 37.  38.     / Post a message and delay its execution for 10 minutes. 39.

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論