내 프로그램은 다른 스레드에서 생성 된 핸들러를 사용하여 해당 스레드에 메시지를 보내려고 할 때 NullPointerException을 던졌습니다. 호출 쓰레드가 이미 다른 쓰레드에서 start를 호출 했음에도 불구하고, 다른 쓰레드에 의해 생성 된 Handler가 아직 생성되지 않았거나 호출 스레드에서 보이지 않았다. 이것은 매우 드물게 발생합니다. 거의 모든 테스트를 실행해도 예외가 발생하지 않습니다.다른 스레드 처리기를 호출하기 전에 null이 아닌지 어떻게 확인합니까?
최소한의 복잡성과 성능 저하로이 문제를 피하는 것이 가장 좋은 방법인지 궁금합니다. 이 프로그램은 게임이며 매우 성능에 민감합니다. 특히 한번 실행하면됩니다. 따라서 예를 들어 설정 후 동기화를 사용하지 않으려 고하고 언제든지 변수를 회전하지 않는 것을 선호합니다.
배경 :
안드로이드에서 처리기 클래스는 "자신의 것과 다른 스레드에서 수행 할 작업을 대기열에 넣기"위해 사용될 수 있습니다. 여기에 문서 :
http://developer.android.com/intl/de/reference/android/os/Handler.html
처리기는 사용할 스레드에서 만들어야합니다. 따라서 해당 스레드를 생성하는 스레드가 실행하는 스레드 생성자에서 생성하는 것은 옵션이 아닙니다. 처리기는 UI 스레드 이외의 스레드이면
는 루퍼 클래스는 사용되어야
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
:
http://developer.android.com/intl/de/reference/android/os/Looper.html
문서가이 목적을 위해 두 클래스를 사용하는 예를 제공한다
내 매우 추한 해결 방법은 현재 다음과 같습니다
public class LooperThread extends Thread {
public volatile Handler mHandler;
public final ArrayBlockingQueue<Object> setupComplete = new ArrayBlockingQueue<Object>(1);
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
setupComplete();
Looper.loop();
}
public void waitForSetupComplete() {
while (true) {
try {
setupComplete.take();
return;
} catch (InterruptedException e) {
//Ignore and try again.
}
}
}
private void setupComplete() {
while(true) {
try {
setupComplete.put(new Object());
return;
} catch (InterruptedException e) {
//Ignore and try again.
}
}
}
}
을 대구로 e를 만드는 스레드에서 다음과 같이 표시됩니다.
LooperThread otherThread = new LooperThread();
otherThread.start();
otherThread.waitForSetupComplete();
otherThread.mHandler.sendEmptyMessage(0);
더 좋은 해결책이 있습니까? 감사.
아, 좋은. HandlerThread # getLooper는 여분의 복잡성을 처리해야하는 대신 차단을 할 수 있습니다. 내 응용 프로그램에서는 HandlerThread를 서브 클래스화할 필요조차 없습니다. –