티스토리 뷰


안녕하세요 박스여우입니다.

이번에는 다른 쓰레드 상에서 UI를 다루는 방법에 대해 다루도록 하겠습니다.


앱 개발을 하던중에 네트워킹을 요구하는 작업이 필요해 별도의 쓰레드를 사용하는데, 그 쓰레드에서 UI까지 호출했더니 골치아픈 일이 벌어졌습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.textview);
        new test().start();
    }
    
    private class test extends Thread{
        @Override
        public void run(){
int count=0;
            while(true){
                try {
                    Thread.sleep(1000); 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
                tv.setText(count);
            }
        }
    }
cs

위의 코드와 같이 앱이 실행될 때 시작되는 메인쓰레드가 아닌 다른 쓰레드 상에서 UI를 호출하려 하면 에러가 발생합니다. 저 같은 경우는 아래처럼 오류가 날때도 있고, MainThread가 아닌 쓰레드로 UI를 건드릴 수 없다고 출력 될 때도 있습니다.






Only the original thread that created a ciew hierarchy can touch its views : 오직 원조 쓰레드 만이 View를 만들 수 있고, 건드릴 수 있다고 합니다.

그럼 어떻게 해야 할까 고민하던중.. UIThread를 찾아냈습니다. 아마 안드로이드는 보여주는게(UI)가 중요하기 때문에 UI를 메인쓰레드에서만 다룰 수 있게 하고, 만약 다른 쓰레드에서 UI를 건들여야 한다면 별도의 UIThread를 이용해 안전하게 UI를 다루도록 하는 것 같습니다.





그래서, UIThread가 뭐냐?

1
2
3
4
5
6
runOnUiThread(new Runnable() {
    @Override
    public void run() {
 
    }
});
cs

위의 코드처럼 사용하는 요상한 쓰레드 입니다. 이 쓰레드는 메인쓰레드가 아니여도 UI를 건들이고 수정할 수 있습니다. 하지만, 한가지 단점이 있습니다. 이 UiThread에 사용되는 변수들은 내부 지역변수가 아니면 모두 상수여야만 합니다.




그럼 처음 코드를 정상 작동하도록 바꿔보면, 아래 코드로 완성됩니다!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    private class test extends Thread{
        @Override
        public void run(){
            int count =0;
            while(true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
                final int co= count;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv.setText(co + "");
                    }
                });
            }
        }
    }
cs




댓글
  • 프로필사진 test 이것은 동작하지 않습니다. UI스레드가 필요합니다.
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    2020.09.07 21:32
댓글쓰기 폼
Total
498,444
Today
26
Yesterday
452
링크
«   2020/10   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함