Android内存泄漏之静态类和静态变量

先看一个例子:

 private static Drawable sBackground;

 @Override
 protectedvoid onCreate(Bundle state){
     super.onCreate(state);
  
     TextView label =newTextView(this);
     label.setText("Leaks are bad");
    
    if(sBackground ==null){
      sBackground = getDrawable(R.drawable.large_bitmap);
    }
    label.setBackgroundDrawable(sBackground);
   
    setContentView(label);
 }

 

上面几行代码,内存泄露挺严重的。sBackground是一个 static 变量,在 label调用setBackgroundDrawable的时候,会调用sBackground的setCallback,所以在 sBackground中就存在label的引用。

而,label中又存在Activity的引用,所以此Activity一直不会被回收,即使已经finish了。

如何避免:

  1. 使用applicationContext作为上下文,避免使用activity
  2. 设置Drawable的Callback为null
  3. 在Service或者Activity使用内部类尽量使用static类。例如:使用Handler

 

关于第3点,看个例子:

    static class IncomingHandlerextendsHandler {
         private final WeakReference<UDPListenerActivity> mActivity;
 
         IncomingHandler(UDPListenerActivity activity) {
             mService = newWeakReference < UDPListenerActivity > (activity);
          }
   
        @Override
         public void handleMessage(Message msg) {
             UDPListenerActivity activity = mActivity.get();
             if (activity != null) {
                 activity.handleMessage(msg);
             }
         }
    } 

 

我们知道,Message发出之后是存在MessageQueue中的,有些 Message也不是马上就被处理的。
 
在Message存在一个 target,是Handler的一个引用,如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。如果Handler是非静态的,则会导致Activity或者Service不会被回收。
 
所以正确处理Handler等之类的内部类,应该采用上述代码。
 
原文地址:http://www.cnblogs.com/halzhang/archive/2013/05/09/3069609.html

 

posted @ 2013-05-09 22:02  屁颠  阅读(3098)  评论(0编辑  收藏  举报