自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

移動開發(fā) Android
在編寫程序時,一般調(diào)用API獲取服務(wù)器數(shù)據(jù)時,我們都是采取線程來操作的,這里面就需要用到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.   

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

為什么會是這樣呢?

了解一下Handler

  1. 當Android程序***次創(chuàng)建的時候,在主線程同時會創(chuàng)建一個Looper對象。Looper實現(xiàn)了一個簡單的消息隊列,一個接著一個處理Message對象。程序框架所有主要的事件(例如:屏幕上的點擊時間,Activity生命周期的方法等等)都包含在Message對象中,然后添加到Looper的消息隊列中,一個一個處理。主線程的Looper存在整個應(yīng)用程序的生命周期內(nèi)。
  2. 當一個Handler對象在主線程中創(chuàng)建的時候,它會關(guān)聯(lián)到Loopermessage queue 。Message添加到消息隊列中的時候Message會持有當前Handler引用,當Looper處理到當前消息的時候,會調(diào)用Handler#handleMessage(Message).
  3. java中,no-static的內(nèi)部類會 隱式的 持有當前類的一個引用。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ā)送一個10分鐘后執(zhí)行的一個消息 
  15.     mHandler.postDelayed(new Runnable() { 
  16.       @Override 
  17.       public void run() { } 
  18.     }, 600000); 
  19.  
  20.     // 結(jié)束當前的Activity 
  21.     finish(); 
  22.   } 
  23.   

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

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

  1. public class SampleActivity extends Activity { 
  2.  
  3.   /** 
  4.    * 使用靜態(tài)的內(nèi)部類,不會持有當前對象的引用 
  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)部類,不會持有當前對象的引用 
  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ā)送一個10分鐘后執(zhí)行的一個消息 
  37.     mHandler.postDelayed(sRunnable, 600000); 
  38.  
  39.     // 結(jié)束 
  40.     finish(); 
  41.   } 
  42.   

ok,結(jié)束

NOTE: 好多人有擔心弱引用的Activity回收的情況,這個完全不用擔心的,因為我們在這個界面的時候,這個Activity 是不會被回收的,想想 如果我們的這個Activity被回收了,我們的這個界面是怎么存在的呢?

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

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.   
責任編輯:張葉青 來源: 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)存泄露定時器

2014-12-18 10:16:00

Java

2012-04-11 13:46:33

ibmdw

2022-08-05 11:55:13

FlutteriOS

2010-06-02 13:00:43

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

2022-08-26 07:33:49

內(nèi)存JVMEntry

2009-06-16 11:11:07

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

2017-12-11 11:00:27

內(nèi)存泄露判斷

2016-09-08 16:16:26

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

2015-05-14 15:38:40

javajava內(nèi)存泄露

2011-11-17 13:59:41

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

2017-05-04 16:07:11

Tomcat內(nèi)存泄露

2015-12-07 09:39:27

Java內(nèi)存泄露

2010-08-10 10:00:57

Flex內(nèi)存

2022-10-10 11:37:14

Gomap內(nèi)存

2021-12-02 07:50:30

NFS故障內(nèi)存

2024-04-25 10:06:03

內(nèi)存泄漏

2011-07-20 17:04:43

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

2010-10-25 10:10:27

ibmdwJava
點贊
收藏

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