안드로이드의 UI는 단일 스레드 모델이기 때문에 UI단에서 스레드를 사용하고 싶다면 핸들러를 사용해야 합니다.
위와 같은 코드를 실행하게 된다면 해당코드는 다른스레드에서 UI에 접근하기때문에
CalledFromWrongThreadException 예외가 발생하게 되죠
이런 문제를 해결하기 위해 쓰는것이 바로 핸들러가 되겠습니다.
핸들러를 가지고 위의 코드를 수정해 보겠습니다.
이렇게 Handler 인스턴스를 만들어놓고 post안에 Runnable을 구현하면 됩니다.
post안에 Runnable을 구현하는 방법 외에도 많은 방법이 존재합니다.
- CalledFromWrongThreadException 발생 원인 -
왜 다른스레드에서 UI를 변경하려고 하면 해당 예외가 발생하는지 안드로이드 기본소스를 통하여
알아보자면 UI변경이 있게되면 안드로이드 뷰에서는 invalidate를 호출하게 되는데
여기서 보게 되면 invalidate()에서는 ViewParent의 invalidateChild()를 호출하는군요
invalidate()에서는 checkThread()를 호출합니다. checkThread()에서는 위와 같이
현재 실행중인 스레드가 ViewRoot가 가지고 있는 mThread와 참조가 같은지 비교하고
아니라면 CalledFromWrongThreadException 예외를 던지는군요
해결책 2
--------------------------------------------------------------
new Thread(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable(){
@Override
public void run() {
// 해당 작업을 처리함
}
});
}
}).start();
--------------------------------------------------------------
출처 : http://www.androidpub.com/android_dev_info/57470
1.
public
void
onClick(View v) {
2.
new
Thread(
new
Runnable() {
3.
public
void
run() {
4.
txtView.setText(
"안녕하세요?"
);
// 텍스트뷰의 내용변경
5.
}
6.
}).start();
7.
}
위와 같은 코드를 실행하게 된다면 해당코드는 다른스레드에서 UI에 접근하기때문에
CalledFromWrongThreadException 예외가 발생하게 되죠
이런 문제를 해결하기 위해 쓰는것이 바로 핸들러가 되겠습니다.
핸들러를 가지고 위의 코드를 수정해 보겠습니다.
01.
Handler handler =
new
Handler();
02.
03.
public
void
onClick(View v) {
04.
new
Thread(
new
Runnable() {
05.
public
void
run() {
06.
07.
handler.post(
new
Runnable() {
08.
public
void
run() {
09.
txtView.setText(
"이제는 됩니다."
);
10.
}
11.
});
12.
13.
}
14.
}).start();
15.
}
이렇게 Handler 인스턴스를 만들어놓고 post안에 Runnable을 구현하면 됩니다.
post안에 Runnable을 구현하는 방법 외에도 많은 방법이 존재합니다.
- CalledFromWrongThreadException 발생 원인 -
왜 다른스레드에서 UI를 변경하려고 하면 해당 예외가 발생하는지 안드로이드 기본소스를 통하여
알아보자면 UI변경이 있게되면 안드로이드 뷰에서는 invalidate를 호출하게 되는데
1.
// View.java
2.
public
void
invalidate() {
3.
...
4.
final
ViewParent p = mParent;
5.
...
6.
p.invalidateChild(
this
, r);
7.
}
여기서 보게 되면 invalidate()에서는 ViewParent의 invalidateChild()를 호출하는군요
01.
// ViewRoot.java
02.
public
void
invalidateChild(View child, Rect dirty) {
03.
checkThread();
04.
...
05.
}
06.
07.
public
checkThread() {
08.
if
(mThread != Thread.currentThread()) {
09.
throw
new
CalledFromWrongThreadException(
10.
"Only the original thread that created a view hierarchy can touch its views."
);
11.
}
12.
}
invalidate()에서는 checkThread()를 호출합니다. checkThread()에서는 위와 같이
현재 실행중인 스레드가 ViewRoot가 가지고 있는 mThread와 참조가 같은지 비교하고
아니라면 CalledFromWrongThreadException 예외를 던지는군요
해결책 2
--------------------------------------------------------------
new Thread(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable(){
@Override
public void run() {
// 해당 작업을 처리함
}
});
}
}).start();
--------------------------------------------------------------
출처 : http://www.androidpub.com/android_dev_info/57470
'안드로이드' 카테고리의 다른 글
The content of the adapter has changed but ListView did not receive a notification. (0) | 2011.07.12 |
---|---|
안드로이드 안전모드 진입 (0) | 2011.07.12 |
ICU4C 빌드 방법. (0) | 2011.06.22 |
Time Zone 수정 방법. (0) | 2011.06.22 |
Locale Default 설정 및 Use 24-hour format Default 설정 (0) | 2011.06.16 |