본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android/안드로이드] handler 관련 lint (warning) 제거 방법

by 돼지왕 왕돼지 2012. 10. 5.
반응형




Lint 기능이 강화되면서 Handler 쪽에서 발생 안 하던 lint(warning) 가 발생하더군요.

handler should be static, else it is prone to memory leaks

 
바로 요런 해괴한 녀석.

이 녀석이 나오는 원인은 Handler 와 Looper, MessageQueue의 관계.. 그리고 reference 의 관계를 잘 생각해봐야 합니다.

<생각하기>

- Main Thread ( or UI Thread ) 에서 Handler 를 만들게 되면, 해당 Thread 와 연결이 되는 것은 물론, 해당 Activity 혹은 Context 를 참조까지 하게 됩니다. 

- MessageQueue 에 있는 Message 는 Target Handler 를 reference 하고 있습니다. 그래서, Activity 가 종료되어도 MessageQueue에 해당 Handler 에 대한 Message 가 쌓여 있는 경우 Handler 는 GC 되지 않습니다. ( 모든 handler 관련 메세지가 소비되면 GC 가 되기는 하겠죠..? 하지만 최악의 상황에는.. 음.. )

- Handler 가 GC 되지 않으면, Handler 가 참조하는 Activity 도 GC 가 되지 않고 결국 Memory Leak 이 나게 됩니다.



그럼 어떻게 해결해야 하느냐? 다음과 같이 하면 됩니다.

<WeakRefHandler.java>

public class WeakRefHandler extends Handler{

   private final WeakReference<IOnHandlerMessage> mHandlerActivity;

   public WeakRefHandler(IOnHandlerMessage activity) {

      mHandlerActivity = new WeakReference<IOnHandlerMessage>(activity);
    }

   @Override

   public void handleMessage(Message msg) {

      super.handleMessage(msg);

      IOnHandlerMessage activity = (IOnHandlerMessage) mHandlerActivity.get();

      if ( activity == null ) return;

        activity.handleMessage(msg);

   }

}


<IOnHandlerMessage>

public interface IOnHandlerMessage {

  public void handleMessage( Message msg );

}


<사용코드>

class TestActivity extends Activity implements IOnHandlerMessage{
  ..
  WeakRefHandler handler = new WeakRefHandler( this ); 
  ..


위와 같이  WeakReference 를 사용하면, Activity 에 대한 직접적인 참조가 일어나지 않기 때문에 Message Queue 에 해당 handler 관련된 message 가 쌓여있어도, Activity 는 GC 가 일어날 수 있다.
 
 
 
도움이 되셨다면 손가락 꾸욱~ ( 로그인 필요 x )






반응형

댓글