2012-11-22 66 views
5

在下面的代碼中,Eclipse生成警告「這個Handler類應該是靜態的或者可能發生泄漏」。這個Handler類應該是靜態的或者可能發生泄漏:final Handler

public class MyActivity extends Activity implements Runnable 
{ 
    final Handler handler = new Handler() 
    { 
     @Override 
     public void handleMessage(Message message) 
     { 
     String sResult = (String) message.obj; 
     if((sResult != null) && (sResult != "")) 
      { 
      MyNonStatic = (TableLayout) findViewById(R.id.tableLayout); // any non-static method 
      } 
     return; 
     } 
    }; 


    public void run() 
    { 
     final Message message = handler.obtainMessage(1, MyFunction(context)); 
     handler.sendMessage(message); 
    } 

    public String MyFunction(Context context) 
    { 
     return "MyNewString"; 
    } 
    } 

我在網站上回顧了很多主題,但沒有得到解決方案。請幫我看看這段代碼?

添加:我需要在handleMessage()中調用非靜態方法(例如findViewById())!

+0

這是幾乎相同的,因爲這問題:HTTP://計算器。 com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occurrence-incominghandler – ThomasW

回答

2

處理程序 - 處理程序標識回調應該發生的線程。如果爲null,則回調將從進程的線程池中發生。

想象一下情況。一些活動呼叫PendingIntent.send(...)並把non-static inner subclass of Handler。然後活動被破壞。 但內心階層的生活

內部類仍然存在一個被破壞活動的鏈接,它不能被垃圾收集。

因此,您需要將其設爲靜態。

來源:Handlers and memory leaks in Android

+0

Shrikant,我之前閱讀過這個話題。請在我的代碼中使用handleMessage()中的非靜態方法應用... –

+0

Uncle Code Monkey的答案(來自我提供的鏈接)對您有所幫助嗎? – Shrikant

+0

代碼Uncle Code Monkey的幫助,但是當不存在時,調用handleMessage()中的非靜態方法。當需要呼叫非靜態時,他的代碼不起作用。可能是我做錯了什麼? –

2

Android lint checks:警告的

 
HandlerLeak 
----------- 
Summary: Ensures that Handler classes do not hold on to a reference to an 
outer class 

Priority: 4/10 
Severity: Warning 
Category: Performance 

In Android, Handler classes should be static or leaks might occur. Messages 
enqueued on the application thread's 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 WeakReference to its outer class. 

第一部分是因爲final Handler handler = new Handler()創建一個匿名內部類。內部類不能以獨立的方式創建,你總是需要一個外部實例。記住你將如何在Java OuterClass.InnerClass innerObject = outerObject.new InnerClass();中創建它。每個內部類對象還必須保留對外部對象Outer.this的引用以訪問外部成員。

第二部分是final Message message = handler.obtainMessage(1, MyFunction(context));有一個句柄給你的內部處理程序類(它有一個外部Activity類的處理程序)。如果此消息足夠長,則無法收集您的活動。

什麼可以阻止正在處理的郵件?不幸的是,lint工具無法解決這個問題,所以它總是警告你可能會發生內存泄漏。如果您確定自己在做什麼,可以通過various methods來抑制這些消息。

對於您的情況下,它看起來並不像一個好主意,使Activity一個Runnable但無論如何可能是你應該使用Handler.post或最佳Activity.runOnUIThread

4

下面是一個使用弱引用和靜態處理程序類的皮棉文檔中建議解決這個問題的一個例子:

public class MyClass{ 

    //static inner class doesn't hold an implicit reference to the outer class 
    private static class MyHandler extends Handler { 
    //Using a weak reference means you won't prevent garbage collection 
    private final WeakReference<MyClass> myClassWeakReference; 

    public MyHandler(MyClass myClassInstance) { 
     myClassWeakReference = new WeakReference<MyClass>(myClassInstance); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     MyClass myClass = myClassWeakReference.get(); 
     if (myClass != null) { 
     ...do work here... 
     } 
    } 
    } 

    private final MyHandler mHandler = new MyHandler(this); 

    public void getHandler() { 
    return new MyHandler(this); 
    } 
} 
相關問題