Android:秒表应用程序因 CalledFromWrongThreadException 而崩溃
这是我在 Android 上的秒表应用程序的代码:
package com.google.labyrinth;
public class Tabalicious extends Activity implements OnClickListener, Runnable
{
TextView stopwatchCounter;
long startTime, stopTime;
Thread stopwatch;
Button buttonStart;
Button buttonStop;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView( R.layout.tabalicious );
stopwatchCounter = (TextView) findViewById ( R.id.txtStopwatchCounter );
buttonStart = ( Button ) findViewById ( R.id.buttonStart );
buttonStop = ( Button ) findViewById ( R.id.buttonStop );
buttonStart.setOnClickListener( this );
buttonStop.setOnClickListener( this );
buttonStop.setEnabled(false);
}
public void onClick(View viewClicked)
{
switch( viewClicked.getId() )
{
case R.id.buttonStart:
this.buttonStart.setEnabled(false);
this.buttonStop.setEnabled(true);
this.startTime = System.currentTimeMillis();
stopwatch = new Thread(this);
stopwatch.start();
break;
case R.id.buttonStop:
this.buttonStop.setEnabled(false);
this.buttonStart.setEnabled(true);
try {
stopwatch.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
public void run()
{
//Update after 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.stopTime = System.currentTimeMillis();
this.stopwatchCounter.setText( String.valueOf( (this.stopTime - this.startTime) ) ); //<- Debugger Info: This line is at the top of the call stack.
}
}
问题是,当我运行该应用程序时,我收到 CalledFromWrongThread 异常:
02-10 19:53:32.835:E/AndroidRuntime(18482):致命异常: 线程 10 02-10 19:53:32.835: E/AndroidRuntime(18482):
android.view.ViewRoot$CalledFromWrongThreadException:仅 创建视图层次结构的原始线程可以触摸其视图。 02-10 19:53:32.835: E/AndroidRuntime(18482):
在 android.view.ViewRoot.checkThread(ViewRoot.java:3092) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.view.ViewRoot.invalidateChild(ViewRoot.java:677) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:703) 02-10 19:53:32.835: E/AndroidRuntime(18482):
在 android.view.ViewGroup.invalidateChild(ViewGroup.java:2597) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.view.View.invalidate(View.java:5326) 02-10 19:53:32.835: E/Android运行时(18482):
在 android.widget.TextView.checkForRelayout(TextView.java:5761) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.widget.TextView.setText(TextView.java:2814) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.widget.TextView.setText(TextView.java:2682) 02-10 19:53:32.835:E/AndroidRuntime(18482):
在 android.widget.TextView.setText(TextView.java:2657) 02-10 19:53:32.835: E/AndroidRuntime(18482): 在 com.google.labyrinth.Tabalicious.run(Tabalicious.java:144) 02-10 19:53:32.835: E/AndroidRuntime(18482): 在 java.lang.Thread.run(Thread.java:1027)
我不太清楚发生了什么。我将不胜感激你的帮助。谢谢!
Here's my code for a stopwatch application on Android:
package com.google.labyrinth;
public class Tabalicious extends Activity implements OnClickListener, Runnable
{
TextView stopwatchCounter;
long startTime, stopTime;
Thread stopwatch;
Button buttonStart;
Button buttonStop;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView( R.layout.tabalicious );
stopwatchCounter = (TextView) findViewById ( R.id.txtStopwatchCounter );
buttonStart = ( Button ) findViewById ( R.id.buttonStart );
buttonStop = ( Button ) findViewById ( R.id.buttonStop );
buttonStart.setOnClickListener( this );
buttonStop.setOnClickListener( this );
buttonStop.setEnabled(false);
}
public void onClick(View viewClicked)
{
switch( viewClicked.getId() )
{
case R.id.buttonStart:
this.buttonStart.setEnabled(false);
this.buttonStop.setEnabled(true);
this.startTime = System.currentTimeMillis();
stopwatch = new Thread(this);
stopwatch.start();
break;
case R.id.buttonStop:
this.buttonStop.setEnabled(false);
this.buttonStart.setEnabled(true);
try {
stopwatch.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
}
public void run()
{
//Update after 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.stopTime = System.currentTimeMillis();
this.stopwatchCounter.setText( String.valueOf( (this.stopTime - this.startTime) ) ); //<- Debugger Info: This line is at the top of the call stack.
}
}
The problem is that when I run the application I get a CalledFromWrongThread exception:
02-10 19:53:32.835: E/AndroidRuntime(18482): FATAL EXCEPTION:
Thread-10 02-10 19:53:32.835: E/AndroidRuntime(18482):android.view.ViewRoot$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
02-10 19:53:32.835: E/AndroidRuntime(18482):at android.view.ViewRoot.checkThread(ViewRoot.java:3092) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.view.ViewRoot.invalidateChild(ViewRoot.java:677) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:703)
02-10 19:53:32.835: E/AndroidRuntime(18482):at android.view.ViewGroup.invalidateChild(ViewGroup.java:2597) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.view.View.invalidate(View.java:5326) 02-10 19:53:32.835:
E/AndroidRuntime(18482):at android.widget.TextView.checkForRelayout(TextView.java:5761) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.widget.TextView.setText(TextView.java:2814) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.widget.TextView.setText(TextView.java:2682) 02-10
19:53:32.835: E/AndroidRuntime(18482):at android.widget.TextView.setText(TextView.java:2657) 02-10
19:53:32.835: E/AndroidRuntime(18482): at
com.google.labyrinth.Tabalicious.run(Tabalicious.java:144) 02-10
19:53:32.835: E/AndroidRuntime(18482): at
java.lang.Thread.run(Thread.java:1027)
I'm not quite clear on what's going on. I would appreciate your help. thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在尝试编辑 UI 元素,但不在 UI 线程上。在Android中,UI元素只能由UI线程编辑。在另一个线程上执行计算后更新 UI 元素的方法有很多,包括调用 runOnUiThread() 方法、使用 Handler 或重写 AsyncTask 的 PostExecute() 方法。
You are trying to edit UI elements but you are not on the UI thread. In Android, UI elements can only be edited by the UI thread. There are many ways to update UI elements after doing computation on another thread, including calling the runOnUiThread() method, using a Handler, or overriding the PostExecute() method of an AsyncTask.
这只是因为你这样做:
this.stopwatchCounter.setText( String.valueOf( (this.stopTime - this.startTime) ) );
在秒表线程内,您无法触摸视图,因为它不是 UIThread。
this is only because you do :
this.stopwatchCounter.setText( String.valueOf( (this.stopTime - this.startTime) ) );
inside stopwatch thread, you can't touch the view because it isn't the UIThread.