티스토리 뷰

Mobile/Android

[Android] Runnable

춘햄 2022. 4. 6. 08:07

직전 포스팅에서 스레드와 핸들러를 이용하여 새 스레드에서 메인 스레드를 제어할 수 있는 방법을 확인했는데, 핸들러 객체를 생성하고 스레드에서 이를 활용하기 위해 작성한 코드가 조금 복잡해 보인다는 단점이 있다. 핸들러 클래스는 메시지큐를 이용한 데이터 전송 방법 이외에도 Runnable 객체를 실행할 수 있는 방법을 제공한다. 

 

바로 확인해보자.


◎MainActivity.java

package com.example.samplethread;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    int value = 0;
    TextView textView;

    Handler handler = new Handler(Looper.getMainLooper());
    // Handler() <== deprecated: Handler 생성 중에 암시 적으로 Looper를 선택하면 작업이 자동으로 손실 
    // (Handler가 새 작업을 예상하지 않고 종료되는 경우),
    // 충돌 (Looper가 활성화되지 않은 스레드에서 처리기가 생성되는 경우) 또는 경쟁 조건이 발생하는 버그가 발생할 수 있습니다.
    // 따라서 생성자에 Looper를 명시해주도록 하자.
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.textView2);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });

    }

    class BackgroundThread extends Thread {
        public void run() {
            for(int i = 0; i < 100; i++) {
                try{
                    Thread.sleep(1000);
                } catch (Exception e) {}

                value ++;

                Log.d("Thread", "value : " + value);
                
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("value: " + value);
                    }
                });
            }
        }
    }

}

핸들러 객체의 post() 를 사용하여 Runnable 객체를 전달해주면, Runnable에 정의된 run() 메서드에서 위와 같이 메인 스레드를 제어할 수 있다.

 

핸들러의 메시지 큐 객체를 직접 참조하여 메인 스레드를 제어하는 것보다 훨씬 간단하기 때문에, 실제 앱 개발에서는 이 방법을 많이 사용한다.

 

반응형

'Mobile > Android' 카테고리의 다른 글

[Android] Thread로 메시지 전송  (0) 2022.04.07
[Android] Runnable 2: postDelayed  (0) 2022.04.06
[Android] Thread & Handler  (0) 2022.04.05
[Android] 선택 위젯 4: Spinner  (0) 2022.04.03
[Android] 선택 위젯 3: Recycler View  (0) 2022.04.03
Comments