我遇到了有关线程层次结构的错误。我知道问题出在哪里,但我不明白线程足以理解为什么会发生这种情况。
我将此作为我的基本代码:
public class CameraPage extends Activity implements ImageSaver.OnImageSavedListener {
public int numPics = 0;
public Timer gifTimer;
protected void onCreate(Bundle savedInstanceState) {
gif_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
countdownTimer = new CountDownTimer((seconds * 1000 + 500), 1000) {
public void onTick(long millisUntilFinished) {
// Do things
}
public void onFinish() {
numPics = 0;
gifTimer = new Timer();
gifTimer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run(){
numPics++;
if(numPics <= 5) {
Log.d("********", "Take a picture " + numPics);
} else {
gifTimer.cancel();
Log.d("********", "No More Pictures " + numPics);
setCameraSpace();
}
}
},0,500);
}
}.start();
}
});
然后setCameraSpace()
的方法就在这里。除了改变任何View
的可见性之外,它的作用都不重要。
public void setCameraSpace(){
Log.d("***********", "Finish " + bitmapArray);
if (icon_alert_int == 1) {
icon_alert.setVisibility(View.VISIBLE);
} else {
icon_alert.setVisibility(View.GONE);
}
if(gallery){
gallery_button.setVisibility(View.VISIBLE);
} else {
gallery_button.setVisibility(View.GONE);
}
camera_preview_container.setVisibility(View.GONE);
countdown_timer.setVisibility(View.GONE);
picture_button.setVisibility(View.VISIBLE);
back_button.setVisibility(View.VISIBLE);
front_flash.setVisibility(View.GONE);
front_flash.setAlpha(0f);
countdown_timer.setText("");
camera_text.setText(pref_session_start_inp);
if (pref_session_auto_live_view) {
//Countdown until Live view reappears
live_view_timer = new CountDownTimer((pref_session_auto_live_view_inp * 1000 + 50), 1000) {
public void onTick(long millisUntilFinished) {
auto_live_view_text.setText("" + ((millisUntilFinished / 1000) - 1));
}
public void onFinish() {
latest_picture_container.setVisibility(View.GONE);
camera_preview_container.setVisibility(View.VISIBLE);
auto_live_view_text.setText(String.valueOf(pref_session_auto_live_view_inp));
camera_text.setText(pref_session_start_inp);
}
}.start();
}
}
所以,我不确定线程以及何时开始/结束以及如何将东西放在不同的地方。我假设setCameraSpace()
中的UI元素不属于不同的数据类型线程,因为它位于run()
?
无论如何,我收到了这个错误:
FATAL EXCEPTION: Timer-0
Process: com.cleanercoding.cleanerphotobooth, PID: 14355
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7647)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1107)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5029)
at android.view.View.invalidateInternal(View.java:12953)
at android.view.View.invalidate(View.java:12917)
at android.view.View.setFlags(View.java:10850)
at android.view.View.setVisibility(View.java:7233)
at android.widget.ImageView.setVisibility(ImageView.java:1420)
at com.cleanercoding.cleanerphotobooth.CameraPage.setCameraSpace(CameraPage.java:1263)
at com.cleanercoding.cleanerphotobooth.CameraPage$6$2$1.run(CameraPage.java:552)
at java.util.Timer$TimerImpl.run(Timer.java:284)
答案 0 :(得分:1)
查看Timer
(http://developer.android.com/reference/java/util/Timer.html)的文档,看来Timer对象有自己的线程,在该线程中,它按顺序执行任务。这意味着可以从Timer
拥有的线程访问UI,而不是UI拥有的线程。
有关使用线程时如何与UI通信的信息,请参阅http://developer.android.com/training/multiple-threads/communicate-ui.html。