Java 是否已经有适用于 android 的 StopWatch 类,为什么我的实现不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21981817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there already a StopWatch class for android and why doesn't my implementation work?
提问by principal-ideal-domain
Lately I saw http://developer.android.com/reference/android/os/CountDownTimer.htmland wondered if there is an respective class for stop watches since I want to tell the user of my App how long he's already trying to solve the puzzle. I mean it isn't that complicated to program such a stop watch on your own. I tried something like
最近我看到了http://developer.android.com/reference/android/os/CountDownTimer.html并想知道是否有相应的秒表类,因为我想告诉我的应用程序的用户他已经尝试解决多长时间了谜题。我的意思是自己编写这样一个秒表并没有那么复杂。我试过类似的东西
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
long seconds = (System.currentTimeMillis() - t) / 1000;
statusBar.setText(String.format("%02d:%02d", seconds / 60, seconds % 60));
}
}
};
statusBar.post(runnable);
But bizarrely the layout of my activity isn't inflated anymore since I have this statusBar.post(runnable);
in the end of the acitivity's onCreate
method meaning that after starting the app I only see a white screen instead of the normal gui.
但奇怪的是,我的活动布局不再膨胀,因为我statusBar.post(runnable);
在活动onCreate
方法的末尾有这个,这意味着在启动应用程序后,我只看到一个白屏而不是正常的 gui。
采纳答案by Yaroslav Mytkalyk
You should use a Chronometer.
您应该使用天文台。
But anyway, your code can work if you remove the sleep from UI thread.
但无论如何,如果您从 UI 线程中删除睡眠,您的代码就可以工作。
private final Runnable mRunnable = new Runnable() {
@Override
public void run() {
if (mStarted) {
long seconds = (System.currentTimeMillis() - t) / 1000;
statusBar.setText(String.format("%02d:%02d", seconds / 60, seconds % 60));
handler.postDelayed(runnable, 1000L);
}
}
};
private Hanlder mHandler;
private boolean mStarted;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
}
@Override
protected void onStart() {
super.onStart();
mStarted = true;
mHandler.postDealyed(runnable, 1000L);
}
@Override
protected void onStop() {
super.onStop();
mStarted = false;
mHandler.removeCallbacks(mRunnable);
}
回答by laalto
Why your code doesn't work is because you post a Runnable
to the UI thread message queue. The runnable runs forever in the while
loop, preventing the UI thread from doing any other business, such as drawing your layout and responding to inputs.
为什么您的代码不起作用是因为您将 a 发布Runnable
到 UI 线程消息队列。runnable 在while
循环中永远运行,阻止 UI 线程执行任何其他业务,例如绘制布局和响应输入。
Using Thread.sleep()
in an UI thread is almost always wrong. Consider using a Timer
instead.
使用Thread.sleep()
在UI线程几乎总是错的。考虑使用 aTimer
代替。
回答by Dan
Have a look at the Chronometerclass.
看看Chronometer类。
Sample code from APIDemo:
来自 APIDemo 的示例代码:
import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;
public class ChronometerDemo extends Activity {
Chronometer mChronometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chronometer);
Button button;
mChronometer = (Chronometer) findViewById(R.id.chronometer);
// Watch for button clicks.
button = (Button) findViewById(R.id.start);
button.setOnClickListener(mStartListener);
button = (Button) findViewById(R.id.stop);
button.setOnClickListener(mStopListener);
button = (Button) findViewById(R.id.reset);
button.setOnClickListener(mResetListener);
button = (Button) findViewById(R.id.set_format);
button.setOnClickListener(mSetFormatListener);
button = (Button) findViewById(R.id.clear_format);
button.setOnClickListener(mClearFormatListener);
}
View.OnClickListener mStartListener = new OnClickListener() {
public void onClick(View v) {
mChronometer.start();
}
};
View.OnClickListener mStopListener = new OnClickListener() {
public void onClick(View v) {
mChronometer.stop();
}
};
View.OnClickListener mResetListener = new OnClickListener() {
public void onClick(View v) {
mChronometer.setBase(SystemClock.elapsedRealtime());
}
};
View.OnClickListener mSetFormatListener = new OnClickListener() {
public void onClick(View v) {
mChronometer.setFormat("Formatted time (%s)");
}
};
View.OnClickListener mClearFormatListener = new OnClickListener() {
public void onClick(View v) {
mChronometer.setFormat(null);
}
};
}
R.layout.chronometer:
R.layout.chronometer:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Chronometer android:id="@+id/chronometer"
android:format="@string/chronometer_initial_format"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingBottom="30dip"
android:paddingTop="30dip"
/>
<Button android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chronometer_start">
<requestFocus />
</Button>
<Button android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chronometer_stop">
</Button>
<Button android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chronometer_reset">
</Button>
<Button android:id="@+id/set_format"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chronometer_set_format">
</Button>
<Button android:id="@+id/clear_format"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/chronometer_clear_format">
</Button>
</LinearLayout>
Add this to Strings.xml
将此添加到 Strings.xml
<string name="chronometer_start">Start</string>
<string name="chronometer_stop">Stop</string>
<string name="chronometer_reset">Reset</string>
<string name="chronometer_set_format">Set format string</string>
<string name="chronometer_clear_format">Clear format string</string>
<string name="chronometer_initial_format">Initial format: <xliff:g id="initial-format">%s</xliff:g></string>
回答by nzala
You should use a Chronometer.
您应该使用Chronometer。
Chronometer mChronometer;
mChronometer = (Chronometer) findViewById(R.id.chronometer1);
long timeWhenStopped = 0;
when we stop the chronometer
当我们停止计时
timeWhenStopped = mChronometer.getBase() - SystemClock.elapsedRealtime();
mChronometer.stop();
the chronometer before starting it
启动前的计时器
mChronometer.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
mChronometer.start();
resetting the chronometer
重置计时器
mChronometer.setBase(SystemClock.elapsedRealtime());
timeWhenStopped = 0;