Dav*_*e.B 451
好吧,因为这还没有解决,有3种简单的方法来处理这个问题.下面是一个示例,显示所有3和底部是一个示例,显示我认为更可取的方法.还记得在onPause中清理你的任务,必要时保存状态.
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class main extends Activity {
TextView text, text2, text3;
long starttime = 0;
//this posts a message to the main thread from our timertask
//and updates the textfield
final Handler h = new Handler(new Callback() {
@Override
public boolean handleMessage(Message msg) {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text.setText(String.format("%d:%02d", minutes, seconds));
return false;
}
});
//runs without timer be reposting self
Handler h2 = new Handler();
Runnable run = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text3.setText(String.format("%d:%02d", minutes, seconds));
h2.postDelayed(this, 500);
}
};
//tells handler to send a message
class firstTask extends TimerTask {
@Override
public void run() {
h.sendEmptyMessage(0);
}
};
//tells activity to run on ui thread
class secondTask extends TimerTask {
@Override
public void run() {
main.this.runOnUiThread(new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text2.setText(String.format("%d:%02d", minutes, seconds));
}
});
}
};
Timer timer = new Timer();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
text2 = (TextView)findViewById(R.id.text2);
text3 = (TextView)findViewById(R.id.text3);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button)v;
if(b.getText().equals("stop")){
timer.cancel();
timer.purge();
h2.removeCallbacks(run);
b.setText("start");
}else{
starttime = System.currentTimeMillis();
timer = new Timer();
timer.schedule(new firstTask(), 0,500);
timer.schedule(new secondTask(), 0,500);
h2.postDelayed(run, 0);
b.setText("stop");
}
}
});
}
@Override
public void onPause() {
super.onPause();
timer.cancel();
timer.purge();
h2.removeCallbacks(run);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
}
}
要记住的主要事情是UI只能从主ui线程修改,所以使用处理程序或activity.runOnUIThread(Runnable r);
这是我认为首选的方法.
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TestActivity extends Activity {
TextView timerTextView;
long startTime = 0;
//runs without a timer by reposting this handler at the end of the runnable
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this, 500);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
timerTextView = (TextView) findViewById(R.id.timerTextView);
Button b = (Button) findViewById(R.id.button);
b.setText("start");
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("stop")) {
timerHandler.removeCallbacks(timerRunnable);
b.setText("start");
} else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("stop");
}
}
});
}
@Override
public void onPause() {
super.onPause();
timerHandler.removeCallbacks(timerRunnable);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
}
}
fic*_*ion 82
很简单!你创建新的计时器.
Timer timer = new Timer();
Run Code Online (Sandbox Code Playgroud)
然后扩展计时器任务
class UpdateBallTask extends TimerTask {
Ball myBall;
public void run() {
//calculate the new position of myBall
}
}
Run Code Online (Sandbox Code Playgroud)
然后以一些更新间隔将新任务添加到Timer
final int FPS = 40;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000/FPS);
Run Code Online (Sandbox Code Playgroud)
免责声明:这不是理想的解决方案.这是使用Timer类的解决方案(由OP提出).在Android SDK中,建议使用Handler类(在接受的答案中有示例).
小智 63
如果您还需要在UI线程上运行代码(而不是在计时器线程上),请查看博客:http://steve.odyfamily.com/?p = 12
public class myActivity extends Activity {
private Timer myTimer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
TimerMethod();
}
}, 0, 1000);
}
private void TimerMethod()
{
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
}
};
}
Run Code Online (Sandbox Code Playgroud)
Ahm*_*azy 38
如果只想在将来安排倒计时,并且在此过程中定期发出通知,则可以使用自API级别1以来可用的CountDownTimer类.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
editText.setText("Seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
editText.setText("Done");
}
}.start();
Run Code Online (Sandbox Code Playgroud)
Jev*_*nov 25
这是一个简单的计时器代码:
Timer timer = new Timer();
TimerTask t = new TimerTask() {
@Override
public void run() {
System.out.println("1");
}
};
timer.scheduleAtFixedRate(t,1000,1000);
Run Code Online (Sandbox Code Playgroud)
Wil*_*ill 10
我认为你可以用Rx方式做到:
timerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
//TODO do your stuff
}
});
Run Code Online (Sandbox Code Playgroud)
取消这个就像:
timerSubscribe.unsubscribe();
Run Code Online (Sandbox Code Playgroud)
Rx计时器http://reactivex.io/documentation/operators/timer.html
小智 9
因为这个问题仍然吸引了很多谷歌搜索用户(关于Android计时器),我想插入我的两个硬币.
首先,Timer类将在Java 9中弃用(阅读已接受的答案).
该负责人建议的方法是使用的ScheduledThreadPoolExecutor这是更有效和更丰富的功能,它可另行安排指挥一个给定的延迟后运行或定期地执行.此外,它还提供了ThreadPoolExecutor的额外灵活性和功能.
以下是使用简单功能的示例.
创建执行程序服务:
final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
Run Code Online (Sandbox Code Playgroud)只安排你运行:
final Future<?> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
Run Code Online (Sandbox Code Playgroud)您现在可以使用future取消任务或检查是否已完成,例如:
future.isDone();
Run Code Online (Sandbox Code Playgroud)希望您会发现这对于在Android中创建任务非常有用.
完整的例子:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Future<?> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
if (sampleFutureTimer.isDone()){
// Do something which will save world.
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶没有答案提到RxJava2解决方案。它非常简单,并提供了一种在Android中设置计时器的简便方法。
首先,您需要设置Gradle依赖关系(如果尚未设置):
implementation "io.reactivex.rxjava2:rxjava:2.x.y"
Run Code Online (Sandbox Code Playgroud)
(替换x并y使用当前版本号)
由于我们只有一个简单的,不可重复的任务,因此我们可以使用Completableobject:
Completable.timer(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
// Timer finished, do something...
});
Run Code Online (Sandbox Code Playgroud)
对于REPEATING TASK,您可以Observable类似的方式使用:
Observable(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tick -> {
// called every 2 seconds, do something...
}, throwable -> {
// handle error
});
Run Code Online (Sandbox Code Playgroud)
Schedulers.computation()确保我们的计时器在后台线程上运行,并且.observeOn(AndroidSchedulers.mainThread())意味着我们在计时器完成后运行的代码将在主线程上完成。
为避免不必要的内存泄漏,您应确保在活动/片段被销毁时退订。
谁想在 kotlin 中做到这一点:
val timer = fixedRateTimer(period = 1000L) {
val currentTime: Date = Calendar.getInstance().time
runOnUiThread {
tvFOO.text = currentTime.toString()
}
}
Run Code Online (Sandbox Code Playgroud)
要停止计时器,您可以使用:
timer.cancel()
Run Code Online (Sandbox Code Playgroud)
这个功能还有很多其他的选择,试试看
| 归档时间: |
|
| 查看次数: |
465332 次 |
| 最近记录: |