我有一个带有一个TextView和两个Buttons的简单程序:Button1和Button2。
单击按钮1将启动一个计数器,每1秒增加1并在TextView上显示结果;按钮2上的叮当声将使其停止。这是我的Button1代码的一部分。但它不起作用。
Timer T=new Timer();
T.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
myTextView.setText("count="+count);
count++;
}
}, 1000, 1000);
我知道使用Thread有一些类似的问题,但似乎他们没有提到停止计数器。
任何建议都非常感谢。
加了:
您好,我刚从一个更大的程序中缩短了我的代码,但它仍然崩溃了:
package com.example.hello;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView myTextView;
int count=0;
Timer T;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView=(TextView)findViewById(R.id.t);
T=new Timer();
T.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
myTextView.setText("count="+count);
count++;
}
}, 1000, 1000);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
日志文件(我不想发布此文件,因为它太长但有人要求它):
07-28 17:35:07.012: W/dalvikvm(11331): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
07-28 17:35:07.016: E/AndroidRuntime(11331): FATAL EXCEPTION: Timer-0
07-28 17:35:07.016: E/AndroidRuntime(11331): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.View.requestLayout(View.java:8125)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.View.requestLayout(View.java:8125)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.View.requestLayout(View.java:8125)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.View.requestLayout(View.java:8125)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.view.View.requestLayout(View.java:8125)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.widget.TextView.checkForRelayout(TextView.java:5378)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.widget.TextView.setText(TextView.java:2688)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.widget.TextView.setText(TextView.java:2556)
07-28 17:35:07.016: E/AndroidRuntime(11331): at android.widget.TextView.setText(TextView.java:2531)
07-28 17:35:07.016: E/AndroidRuntime(11331): at com.example.hello.MainActivity$1.run(MainActivity.java:21)
07-28 17:35:07.016: E/AndroidRuntime(11331): at java.util.Timer$TimerImpl.run(Timer.java:289)
答案 0 :(得分:34)
你可以介绍旗帜。像isPaused
这样的东西。每按一次“暂停”按钮,触发此标志。检查计时器任务中的标志值。成功。
Timer T=new Timer();
T.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable()
{
@Override
public void run()
{
myTextView.setText("count="+count);
count++;
}
});
}
}, 1000, 1000);
onClick(View v)
{
//this is 'Pause' button click listener
T.cancel();
}
答案 1 :(得分:6)
Chekout this示例,使用Chronometer类:http://android-er.blogspot.com/2010/06/android-chronometer.html
使用Chronometer类可以节省您自己管理线程的费用。
答案 2 :(得分:3)
如果您想显示运行时钟,那就是完美的解决方案。
pid
答案 3 :(得分:2)
Pavel在正确的轨道上停下来,除了他的答案是浪费,因为它不会停止计时器。在他发布的部分用添加的else语句执行此操作:
if(!isPaused)
{
myTextView.setText("count="+count);
count++;
} else {
cancel();//adding this makes it actually stop
}
哦,你说它崩溃了。我们不知道它为什么会崩溃,所以不幸的是,除非我们看到更多代码和错误,否则我们无法确定为什么会这样做。
好的捕获@yorkw问题显然是它开始运行时尝试做的事情。由于它说的是“Timer-0”,这意味着它永远不会正式启动而且会陷入那个部分。运行线程的第一条规则,永远不要改变UI外部的UI元素。我建议像约克所说的那样使用runOnUiThread
。以下是有关如何使用它的链接:runOnUiThread。
非常确定TimerTask
是一个可运行的意思,它运行在一个单独的线程上。至少这就是我在文档中注意到的。
答案 4 :(得分:0)
这种方式要简单得多。这项功能可在android开发人员网站上使用。 Link
com.databricks.backend.common.rpc.DatabricksExceptions$SQLExecutionException:
org.apache.spark.sql.AnalysisException: You are trying to create an external
table `default`.`dbo_pedidos` from `/delta/dbo_pedidos` using Databricks
Delta, but the schema is not specified when the input path is empty.
答案 5 :(得分:0)
根据@hovanessyan的建议:您可以使用Chronometer类。 例如,如下(使用Kotlin,Java类似物):
class ChronometerToggler: Fragment() {
private lateinit var chronometer: Chronometer
private var isChronometerRunning = false
private lateinit var toggleButton: FloatingActionButton
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.my_layout, container, false)
chronometer = view.findViewById(R.id.chronometer)
toggleButton = view.findViewById(R.id.toggle_button)
toggleButton.setOnClickListener {
onToggleButtonPressed()
}
return view
}
private fun onToggleButtonPressed() {
isChronometerRunning = !isChronometerRunning
if (isChronometerRunning) {
chronometer.base = SystemClock.elapsedRealtime()
chronometer.start()
}
else {
chronometer.stop()
}
}
}
在my_layout.xml
中:
[...]
<Chronometer android:id="@+id/chronometer" [...]/>
[...]