반응형
This Handler class should be static or leaks might occur
안드로이드에서 Handler 오브젝트는 모든 스레드 반복문에서 참조하는데 어느 한곳에 종속되면 안되기 때문이다.
그렇게 되면 가비지 컬렉션이 되지 않아 Memory leak이 계속해서 발생하게 된다.
핸들러의 하위 클래스를 만들어서 약참조 시킴으로써 해결 할 수 있다.
즉, 사실은 아래와 같은 코드를 쓰면 안된다는 것이다.
package com.example.myhandler;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
static final int THREAD_MSG = 1;
static final int MAIN_MSG = 2;
int num = 0;
TextView textView;
Handler tHandler;
Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch(msg.what) {
case MAIN_MSG:
textView.setText("이것은 메인 핸들러!" + num);
if(num < 10){
num++;
tHandler.sendEmptyMessageDelayed(THREAD_MSG, 1000);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text_view);
Thread thread = new Thread(new MyRunnable());
thread.start();
}
class MyRunnable implements Runnable {
@Override
public void run() {
// 루퍼를 생성시켜 핸들러가 계속 메시지를 수신 할 수 있도록 한다.
Looper.prepare();
tHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case THREAD_MSG:
mHandler.post(new Runnable() {
@Override
public void run() {
textView.setText("이것은 스레드 핸들러! " + num);
if(num < 10){
num++;
mHandler.sendEmptyMessageDelayed(MAIN_MSG, 1000);
}
}
});
break;
}
}
};
// hadler 생성 후 메인으로 메시지를 보낸다.
mHandler.sendEmptyMessage(MAIN_MSG);
Looper.loop();
}
}
}
위와 같은 코드는 결국 두 핸들러 모두 하나에 종속되게 만들었기에 메모리 릭 위험에 빠지게 된다.
잘못된 방식
package com.example.myhandler;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Handler;
import android.os.Message;
public class MainActivity extends AppCompatActivity {
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
}
};
}
해결 방법
package com.example.myhandler;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Handler;
import android.os.Message;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private final MyHandler handler = new MyHandler(this);
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> weakReference;
public MyHandler(MainActivity activity){
this.weakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
// 핸들링 내용 기입
}
}
}
반응형
'Basic > Android' 카테고리의 다른 글
Android에서 폴더 생성(디렉토리 생성)하기 (0) | 2020.01.11 |
---|---|
외부 모듈 import 및 so 파일 추가 (0) | 2019.12.19 |
Easing functions 공식 및 그림 (0) | 2019.12.12 |
다각형 영역으로 이미지 자르기 (0) | 2019.11.19 |
Android 해상도와 dpi, px, dp, dip, sp의 관계 (0) | 2019.11.17 |