成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Handler 引起的內(nèi)存泄露

移動(dòng)開發(fā) Android
在編寫程序時(shí),一般調(diào)用API獲取服務(wù)器數(shù)據(jù)時(shí),我們都是采取線程來操作的,這里面就需要用到Handler了,但是需要我們注意的是Handler很可能引起內(nèi)存的泄露。

先看一組簡單的代碼

  1. public class SampleActivity extends Activity { 
  2.  
  3.   private final Handler mHandler = new Handler() { 
  4.     @Override 
  5.     public void handleMessage(Message msg) { 
  6.       // ...  
  7.     } 
  8.   } 
  9.   

當(dāng)我們這樣寫在一個(gè)Activity中時(shí),Android Lint會(huì)提示我們這樣一個(gè) warning: In Android, Handler classes should be static or leaks might occur.
意思說:在Android中,Handler 類應(yīng)該是靜態(tài)的否則可能發(fā)生泄漏。

為什么會(huì)是這樣呢?

了解一下Handler

  1. 當(dāng)Android程序***次創(chuàng)建的時(shí)候,在主線程同時(shí)會(huì)創(chuàng)建一個(gè)Looper對象。Looper實(shí)現(xiàn)了一個(gè)簡單的消息隊(duì)列,一個(gè)接著一個(gè)處理Message對象。程序框架所有主要的事件(例如:屏幕上的點(diǎn)擊時(shí)間,Activity生命周期的方法等等)都包含在Message對象中,然后添加到Looper的消息隊(duì)列中,一個(gè)一個(gè)處理。主線程的Looper存在整個(gè)應(yīng)用程序的生命周期內(nèi)。
  2. 當(dāng)一個(gè)Handler對象在主線程中創(chuàng)建的時(shí)候,它會(huì)關(guān)聯(lián)到Loopermessage queueMessage添加到消息隊(duì)列中的時(shí)候Message會(huì)持有當(dāng)前Handler引用,當(dāng)Looper處理到當(dāng)前消息的時(shí)候,會(huì)調(diào)用Handler#handleMessage(Message).
  3. java中,no-static的內(nèi)部類會(huì) 隱式的 持有當(dāng)前類的一個(gè)引用。static的類則沒有。

在什么地方引起了內(nèi)存的泄露呢?再看看下面一段代碼

  1. public class SampleActivity extends Activity { 
  2.  
  3.   private final Handler mHandler = new Handler() { 
  4.     @Override 
  5.     public void handleMessage(Message msg) { 
  6.       // ... 
  7.     } 
  8.   } 
  9.  
  10.   @Override 
  11.   protected void onCreate(Bundle savedInstanceState) { 
  12.     super.onCreate(savedInstanceState); 
  13.  
  14.     // 發(fā)送一個(gè)10分鐘后執(zhí)行的一個(gè)消息 
  15.     mHandler.postDelayed(new Runnable() { 
  16.       @Override 
  17.       public void run() { } 
  18.     }, 600000); 
  19.  
  20.     // 結(jié)束當(dāng)前的Activity 
  21.     finish(); 
  22.   } 
  23.   

當(dāng)Activity結(jié)束后,在 Message queue 處理這個(gè)Message之前,它會(huì)持續(xù)存活著。這個(gè)Message持有Handler的引用,而Handler有持有Activity(SampleActivity)的引用,這個(gè)Activity所有的資源,在這個(gè)消息處理之前都不能也不會(huì)被回收,所以發(fā)生了內(nèi)存泄露。

解決辦法,看下面一段代碼

  1. public class SampleActivity extends Activity { 
  2.  
  3.   /** 
  4.    * 使用靜態(tài)的內(nèi)部類,不會(huì)持有當(dāng)前對象的引用 
  5.    */ 
  6.   private static class MyHandler extends Handler { 
  7.     private final WeakReference<SampleActivity> mActivity; 
  8.  
  9.     public MyHandler(SampleActivity activity) { 
  10.       mActivity = new WeakReference<SampleActivity>(activity); 
  11.     } 
  12.  
  13.     @Override 
  14.     public void handleMessage(Message msg) { 
  15.       SampleActivity activity = mActivity.get(); 
  16.       if (activity != null) { 
  17.         // ... 
  18.       } 
  19.     } 
  20.   } 
  21.  
  22.   private final MyHandler mHandler = new MyHandler(this); 
  23.  
  24.   /** 
  25.    * 使用靜態(tài)的內(nèi)部類,不會(huì)持有當(dāng)前對象的引用 
  26.    */ 
  27.   private static final Runnable sRunnable = new Runnable() { 
  28.       @Override 
  29.       public void run() { } 
  30.   }; 
  31.  
  32.   @Override 
  33.   protected void onCreate(Bundle savedInstanceState) { 
  34.     super.onCreate(savedInstanceState); 
  35.  
  36.     //  發(fā)送一個(gè)10分鐘后執(zhí)行的一個(gè)消息 
  37.     mHandler.postDelayed(sRunnable, 600000); 
  38.  
  39.     // 結(jié)束 
  40.     finish(); 
  41.   } 
  42.   

ok,結(jié)束

NOTE: 好多人有擔(dān)心弱引用的Activity回收的情況,這個(gè)完全不用擔(dān)心的,因?yàn)槲覀冊谶@個(gè)界面的時(shí)候,這個(gè)Activity 是不會(huì)被回收的,想想 如果我們的這個(gè)Activity被回收了,我們的這個(gè)界面是怎么存在的呢?

NOTE2: 各位,我是參照AsyncTask ,查看文檔和自己的理解,存在我解釋不了的地方,還望見諒,如有錯(cuò)誤還望見諒。

NOTE3:具體怎么防止泄漏我也說不清楚,但是Handler 下面有一段源碼

  1. final Class<? extends Handler> klass = getClass(); 
  2.             if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && 
  3.                     (klass.getModifiers() & Modifier.STATIC) == 0) { 
  4.                 Log.w(TAG, "The following Handler class should be static or leaks might occur: " + 
  5.                     klass.getCanonicalName()); 
  6.             } 
  7.   
責(zé)任編輯:張葉青 來源: eoe Android開發(fā)者社區(qū)
相關(guān)推薦

2015-01-14 13:50:58

AndroidHandler內(nèi)存泄露

2025-01-08 08:47:44

Node.js內(nèi)存泄露定時(shí)器

2014-12-18 10:16:00

Java

2012-04-11 13:46:33

ibmdw

2022-08-26 07:33:49

內(nèi)存JVMEntry

2010-06-02 13:00:43

Linux 內(nèi)存監(jiān)控

2017-12-11 11:00:27

內(nèi)存泄露判斷

2022-08-05 11:55:13

FlutteriOS

2009-06-16 11:11:07

Java內(nèi)存管理Java內(nèi)存泄漏

2015-05-14 15:38:40

javajava內(nèi)存泄露

2011-11-17 13:59:41

Java內(nèi)存管理內(nèi)存泄露

2015-12-07 09:39:27

Java內(nèi)存泄露

2017-05-04 16:07:11

Tomcat內(nèi)存泄露

2022-10-10 11:37:14

Gomap內(nèi)存

2016-09-08 16:16:26

iOS移動(dòng)應(yīng)用內(nèi)存泄漏

2010-08-10 10:00:57

Flex內(nèi)存

2011-07-20 17:04:43

Objective-C 內(nèi)存 內(nèi)存泄露

2010-09-25 11:23:15

Java內(nèi)存泄露

2010-10-25 10:10:27

ibmdwJava

2020-06-23 09:48:09

Python開發(fā)內(nèi)存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩午夜在线观看 | 黑人巨大精品欧美一区二区免费 | 日本公妇乱淫xxxⅹ 国产在线不卡 | 日韩视频一区在线观看 | 亚洲精品久久久 | 国产一区二区三区四区 | 国产一级片免费在线观看 | 国产成在线观看免费视频 | 青青久久 | a免费观看 | 精品久久久久国产免费第一页 | 久久久久久久97 | 久久久久久免费免费 | 久久久网| 日韩成人精品在线 | 在线观看日韩精品视频 | 天堂男人av | 精久久久 | 在线中文一区 | 日日干日日操 | 久久在线视频 | 欧美电影在线观看网站 | 九九精品在线 | 久久国产精品免费 | 欧美 日韩 国产 成人 在线 91 | 亚洲在线免费 | 在线免费观看视频黄 | 一级毛片免费完整视频 | 成人在线免费视频 | 中文字幕一区二区三区精彩视频 | 色爱综合网 | 欧美一区二区在线 | 久久综合久久综合久久 | 国产精品久久久久久一区二区三区 | 久久久www成人免费无遮挡大片 | 免费观看色| 国产农村一级片 | 亚洲精品成人在线 | 成人中文字幕在线 | 日韩在线视频网址 | 日韩欧美国产一区二区三区 |