본문 바로가기
안드로이드

[Android] Only the original thread that created a view hierarchy can touch its views 에러 해결

by 코딩히어로 2022. 10. 27.
728x90

title


안드로이드에서 Thread를 사용하여 프로그래밍을 진행할 경우

종종 다음과 같은 에러 문구를 만나게 됩니다

CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views.

해당 에러를 직역하게 되면 View 객체의 UI를 변경하려고 하는데 해당 행위는

Original Thread로만 접근이 가능하다는 의미로 즉 MainThread에서 UI를 변경해야 하는데

Sub Thread에서 UI변경작업을 했기에 발생하는 에러라는 의미입니다

 

해당 에러는 다음과 같은 문구에서 발생했습니다

class TestProcess extends Thread {
    private boolean stop = true;
    private String master_str,slave_str;

    public void setRun(boolean stop) {
        this.stop = stop;
    }

    @Override
    public void run() {
        while (stop != false) {
            master_str = "";
            slave_str = "";
            for(int i=0;i<master_client.size();i++){
                master_str = master_str + master_client.get(i).GetId() + "\n";
            }
            for(int i=0;i<slave_client.size();i++){
                slave_str = slave_str + slave_client.get(i).GetId() + "\n";
            }
            master_detect_list.setText(master_str);
            slave_detect_list.setText(slave_str);
            SystemClock.sleep(100);
        }
    }
}

위 코드는 100미리마다 데이터를 체크하여 TextView에 Text를 변경해주는 Sub Thread입니다

해당 에러가 발생한 부분은 SystemClock.sleep 위쪽 두줄인데요

MainThread가 아닌 SubThread에서 setText를 통한  UI 변경이 있었습니다

 

안드로이드에서 MainThread에게 작업을 전달할 때에는 Handler를 이용하는데

위 코드에서도 UI변경 작업을 Handler를 통해 MainThread에게 지시만 해주면 문제가 해결됩니다

class TestProcess extends Thread {
    private boolean stop = true;
    private String master_str,slave_str;

    public void setRun(boolean stop) {
        this.stop = stop;
    }

    @Override
    public void run() {
        while (stop != false) {
            master_str = "";
            slave_str = "";
            for(int i=0;i<master_client.size();i++){
                master_str = master_str + master_client.get(i).GetId() + "\n";
            }
            for(int i=0;i<slave_client.size();i++){
                slave_str = slave_str + slave_client.get(i).GetId() + "\n";
            }
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    master_detect_list.setText(master_str);
                    slave_detect_list.setText(slave_str);
                }
            });
            SystemClock.sleep(100);
        }
    }
}

new Handler를 통해 post로 UI 변경 작업을 전달합니다

이렇게 해당 에러를 쉽게 해결할 수 있습니다

728x90
반응형

댓글