Android & Kotlin

Thread 에서 UI 접근

쉽코기 2021. 6. 14. 13:33

 

안드로이드에서는 MainThread 에서 UI 를 담당하고 있고 다른 thread를 통한 UI에 직접적 접근을 

금한다. 따라서 handler를 통해 mainThread를 제외한 다른 thread 의 작업 내용을 mainThread 에 전달하는 방법으로  UI를 변경할 수 있다. 

 

방법 1 : 원리를 이해할 수 있는 정석적 방법

// 정석

 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });

//쓰레드 정의

    class BackgroundThread extends Thread {
        int value = 0;
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                value += 1;

                Message message = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("value", value);
                message.setData(bundle);

                handler.sendMessage(message);
            }

        }
        
 // 핸드러 정의
  class MainHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            int value = bundle.getInt("value");
            textView.setText("vlue는" + value);
        }
    }

 

정석적인 방법에서는 핸들러가 관리하는 메세지 객체를 obtainMessage() 를 통해 참조하고 해당 message를 sendMessage 를 통해서 넘겨준다. UI 를 바꾸는 작업은 Handler 에 정의 해주면 handler 안에 handleMessage 는 mainThread 에서 실행되게 된다.

 

 

방법2 : 일반적으로 사용하는 편한 방법 (runndale 객체 이용)

 

 
 //handler 변수 전역으로 선언 
 
 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                BackgroundThread thread = new BackgroundThread();
                thread.start();
            }
        });
        
 class BackgroundThread extends Thread {
        int value = 0;

        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {}
                value += 1;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("value " + value);
                    }
                });
            }
        }
    }

handler 에 post 를 이용해서 수행 내용을 추가하여 보다 쉽게 사용할 수 있다.