Please Enable JavaScript!
Gon[ Enable JavaScript ]

반응형

안드로이드(Android) This Handler class should be static or leaks might occur 해결

 

환경 : Eclipse Mars, Android 4.2.2

 

안드로이드에서 Handler 오브젝트는 모든 스레드 반복문에서 참조하는데 어느 한곳에 종속되면 안되기 때문입니다. 그렇게 되면 가비지 컬렉션이 되지 않아 메모리릭이 계속해서 발생하게 되는 것이죠.

 

아래 그림은 This Handler class should be static or leaks might occur 경고가 나 있는 소스를 캡쳐한 것입니다.

 

 

이것을 해결하기 위해 Handler 를 상속받은 클래스를 하나 만들어 static 등록해 놔야 합니다. 아래 소스는 이전 소스이며 이것을 고쳐보도록 하겠습니다.

 

handler = new Handler() {
	@Override
	public void handleMessage(Message msg) {
		// super.handleMessage(msg);
		if (myTextOn) {
			myTextOn = false;
			myText.setVisibility(View.GONE);
		} else {
			myTextOn = true;
			myText.setVisibility(View.VISIBLE);
		}
	}
};

 

Static 클래스를 하나 만듭니다. 그리고 handleMessage() 함수를 오버라이드 해서 메인 activity 에 미리 만들어 놓은 handleMessage() 호출해 줍니다. 호출할때 스레드에서 전달받은 메시지를 메인으로 보내면 되겠죠

 

private final MyHandler mHandler = new MyHandler(this);

// 핸들러 객체 만들기 
private static class MyHandler extends Handler {
	private final WeakReference<BackgroundThreadActivity> mActivity;
	public MyHandler(BackgroundThreadActivity activity) {
		mActivity = new WeakReference<BackgroundThreadActivity>(activity);
	}

	@Override
	public void handleMessage(Message msg) {
		BackgroundThreadActivity activity = mActivity.get();
		if (activity != null) {
			
	        activity.handleMessage(msg);
		}
	}
}

 

Handler 객체에서 전달받은 메시지는 메인 activity handleMessage 에서 받아 처리합니다.

 

// Handler 에서 호출하는 함수 
private void handleMessage(Message msg) {
    if (myTextOn) {
		myTextOn = false;
		myText.setVisibility(View.GONE);
	} else {
		myTextOn = true;
		myText.setVisibility(View.VISIBLE);
	}
}

 

스레드와 Handler 클래스가 포함된 전체 activity 소스입니다.

 

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class BackgroundThreadActivity extends Activity {

	BackgroundThread backgroundThread;
	TextView myText;
	private boolean myTextOn = true;
	//private static Handler handler;
	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_background_thread);

		myText = (TextView) findViewById(R.id.mytext);

		Toast.makeText(this, "onCreate()", Toast.LENGTH_LONG).show();
	}
	
	private final MyHandler mHandler = new MyHandler(this);
	
	// 핸들러 객체 만들기 
	private static class MyHandler extends Handler {
		private final WeakReference<BackgroundThreadActivity> mActivity;
		public MyHandler(BackgroundThreadActivity activity) {
			mActivity = new WeakReference<BackgroundThreadActivity>(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			BackgroundThreadActivity activity = mActivity.get();
			if (activity != null) {
				
		        activity.handleMessage(msg);
			}
		}
	}
	
	// Handler 에서 호출하는 함수 
	private void handleMessage(Message msg) {
	    if (myTextOn) {
			myTextOn = false;
			myText.setVisibility(View.GONE);
		} else {
			myTextOn = true;
			myText.setVisibility(View.VISIBLE);
		}
	}
	
	@Override
	protected void onStart() {
		super.onStart();

		backgroundThread = new BackgroundThread();
		backgroundThread.setRunning(true);
		backgroundThread.start();
		Toast.makeText(this, "onStart()", Toast.LENGTH_LONG).show();
	}

	@Override
	protected void onStop() {
		super.onStop();

		boolean retry = true;
		backgroundThread.setRunning(false);

		while (retry) {
			try {
				backgroundThread.join();
				retry = false;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
	}

	public class BackgroundThread extends Thread {

		boolean running = false;

		void setRunning(boolean b) {
			running = b;
		}

		@Override
		public void run() {
			while (running) {
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				mHandler.sendMessage(mHandler.obtainMessage());
			}
		}
	}
}

반응형
Posted by 녹두장군1
,