Handler는 잘 사용하지 않는데, Handler를 이용한 코딩이 필요하여 다시 Handler 개념 살펴보면서 적어둔다.
public class HandlerActivity extends AppCompatActivity { Handler mainThreadHandler;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thread);
mainThreadHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 1){ } } }; } } |
public class HandlerActivity extends AppCompatActivity { CHandler mainThreadHandler;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thread);
mainThreadHandler = new Handler(); } private class CHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 1){ //handle message } } } }
|
보통의 경우 위와 같이 Handler 클래스를 생성하는 방법으로 사용한다. 하지만 이런 방식의 경우 "The handler class should be static or leak might occur." 라는 메모리 누수 경고 문구가 발생할 수 있다.
Activity가 종료되더라도 Garbage collect 가 실행되지 않게 되고 결국 Message가 Message Queue에 상당 시간동안 남아있게 되어 Memory Leak 의 원인이 된다.
이를 해결할 방법은 static inner class 로 Handler를 정의해주고 WeakReference 를 이용하여 Activity 메소드를 호출하는 코드를 구현한다.
import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView;
import java.lang.ref.WeakReference;
public class HandlerActivity extends AppCompatActivity { Button handlerStartButton; Button handlerStopButton; Handler mainThreadHandler; static TextView handlerExampleTextView; static int workValue = 0; boolean running = true;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler);
handlerStartButton = findViewById(R.id.btn_start); handlerStopButton = findViewById(R.id.btn_stop); handlerExampleTextView = findViewById(R.id.tv);
mainThreadHandler = new MyHandler(this);
handlerStartButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { running = true; startCount(); } }); handlerStopButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { running = false; workValue = 0; } }); }
private void startCount(){ // Start a child thread when button is clicked. WorkerThread thread = new WorkerThread(); thread.start(); }
private static class MyHandler extends Handler{ private final WeakReference<HandlerActivity> mActivity;
private MyHandler(HandlerActivity activity) { mActivity = new WeakReference<HandlerActivity>(activity); }
@Override public void handleMessage(Message msg) { HandlerActivity activity = mActivity.get(); if(activity != null){ if(msg.what == 1){ handlerExampleTextView.setText("BackValue:" + workValue); } } } }
private class WorkerThread extends Thread{ @Override public void run() { super.run(); while(running){ workValue++; // 작업스레드 값 증가 try { java.lang.Thread.sleep(1000); // 1000ms(1초)이므로 1초 단위로 실행 System.out.println(java.lang.Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } // Create a message in child thread. Message childThreadMessage = new Message(); childThreadMessage.what = 1; childThreadMessage.arg1 = workValue; // Put the message in main thread message queue. mainThreadHandler.sendMessage(childThreadMessage); }
} } } |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
<Button android:id="@+id/btn_start" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:text="시작"/> <Button android:id="@+id/btn_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="중지"/>
</LinearLayout>
<TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_gravity="center" android:gravity="center" android:text="결과" android:textSize="20dp"/>
</LinearLayout>
|
참조 : https://blog.naver.com/zoomen1004/220053616676