如何在android中设置计时器?
Posted
技术标签:
【中文标题】如何在android中设置计时器?【英文标题】:How to set timer in android? 【发布时间】:2011-06-03 14:50:27 【问题描述】:有人可以举一个简单的例子,每秒更新一个文本字段吗?
我想制作一个飞球,并且需要每秒计算/更新球的坐标,这就是我需要某种计时器的原因。
我没有从here 得到任何东西。
【问题讨论】:
这个类可能有帮助:developer.android.com/reference/android/os/CountDownTimer.html 这会有所帮助。 sampleprogramz.com/android/chronometer.php 【参考方案1】:import kotlin.concurrent.fixedRateTimer
val timer = fixedRateTimer("Tag", false, 1000, 2500) /* Your code here */
使用 Kotlin 非常简单
【讨论】:
【参考方案2】:这是您需要在代码中添加以下类的解决方案。并且您可以直接将视图添加到您的 XML 文件中。
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class TimerTextView extends TextView
private static final int DEFAULT_INTERVAL = 1000;
private Timer timer = new Timer();
private long endTime = 0;
private long interval = DEFAULT_INTERVAL;
private boolean isCanceled = false;
public TimerTextView(Context context)
super(context);
public TimerTextView(Context context, AttributeSet attrs)
super(context, attrs);
public TimerTextView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TimerTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
super(context, attrs, defStyleAttr, defStyleRes);
@Override protected void onDetachedFromWindow()
super.onDetachedFromWindow();
stopTimer();
@Override protected void onVisibilityChanged(View changedView, int visibility)
super.onVisibilityChanged(changedView, visibility);
if (VISIBLE == visibility)
startTimer();
else
stopTimer();
public void setInterval(long interval)
if (interval >= 0)
this.interval = interval;
stopTimer();
startTimer();
public void setEndTime(long endTime)
if (endTime >= 0)
this.endTime = endTime;
stopTimer();
startTimer();
private void startTimer()
if (endTime == 0)
return;
if (isCanceled)
timer = new Timer();
isCanceled = false;
timer.scheduleAtFixedRate(new TimerTask()
@Override public void run()
if (null == getHandler())
return;
getHandler().post(new Runnable()
@Override public void run()
setText(getDurationBreakdown(endTime - System.currentTimeMillis()));
);
, 0, interval);
private void stopTimer()
timer.cancel();
isCanceled = true;
private String getDurationBreakdown(long diff)
long millis = diff;
if (millis < 0)
return "00:00:00";
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
return String.format(Locale.ENGLISH, "%02d:%02d:%02d", hours, minutes, seconds);
//return "$getWithLeadZero(hours):$getWithLeadZero(minutes):$getWithLeadZero(seconds)"
【讨论】:
【参考方案3】:enter code here
Thread th=new Thread(new Runnable()
@Override
public void run()
try for(int i=0;i<5;i++)
b1.setText(""+i);
Thread.sleep(5000);
runOnUiThread(new Runnable()
@Override
public void run()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
pp();
);
catch (InterruptedException e)
e.printStackTrace();
);
th.start();
【讨论】:
【参考方案4】:谁想在 kotlin 中这样做:
val timer = fixedRateTimer(period = 1000L)
val currentTime: Date = Calendar.getInstance().time
runOnUiThread
tvFOO.text = currentTime.toString()
要停止计时器,您可以使用:
timer.cancel()
这个功能还有很多其他的选择,试试看
【讨论】:
【参考方案5】:我很惊讶没有答案会提到RxJava2 的解决方案。它非常简单,并提供了一种在 Android 中设置计时器的简单方法。
首先你需要设置 Gradle 依赖,如果你还没有这样做的话:
implementation "io.reactivex.rxjava2:rxjava:2.x.y"
(将x
和y
替换为current version number)
由于我们只有一个简单的非重复任务,我们可以使用Completable
对象:
Completable.timer(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() ->
// Timer finished, do something...
);
对于REPEATING TASK,您可以以类似的方式使用Observable
:
Observable.interval(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tick ->
// called every 2 seconds, do something...
, throwable ->
// handle error
);
Schedulers.computation()
确保我们的计时器在后台线程上运行,.observeOn(AndroidSchedulers.mainThread())
意味着我们在计时器完成后运行的代码将在主线程上完成。
为避免不必要的内存泄漏,您应该确保在 Activity/Fragment 被销毁时取消订阅。
【讨论】:
这是最干净的方法! 如何取消这些?即当用户按下 UI 上的 [STOP] 按钮并且 Completable 在执行之前被取消。 @SomeoneSomewhere 只需将.subscribe()
方法返回的Subscription
保存在变量中,然后在要停止计时器时调用subscription.unsubscribe()
。【参考方案6】:
对于那些不能依赖Chronometer的人,我根据其中一个建议做了一个实用类:
public class TimerTextHelper implements Runnable
private final Handler handler = new Handler();
private final TextView textView;
private volatile long startTime;
private volatile long elapsedTime;
public TimerTextHelper(TextView textView)
this.textView = textView;
@Override
public void run()
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView.setText(String.format("%d:%02d", minutes, seconds));
if (elapsedTime == -1)
handler.postDelayed(this, 500);
public void start()
this.startTime = System.currentTimeMillis();
this.elapsedTime = -1;
handler.post(this);
public void stop()
this.elapsedTime = System.currentTimeMillis() - startTime;
handler.removeCallbacks(this);
public long getElapsedTime()
return elapsedTime;
使用..只是这样做:
TimerTextHelper timerTextHelper = new TimerTextHelper(textView);
timerTextHelper.start();
.....
timerTextHelper.stop();
long elapsedTime = timerTextHelper.getElapsedTime();
【讨论】:
【参考方案7】:我是这样用的:
String[] array=
"man","for","think"
; int j;
然后在onCreate下面
TextView t = findViewById(R.id.textView);
new CountDownTimer(5000,1000)
@Override
public void onTick(long millisUntilFinished)
@Override
public void onFinish()
t.setText("I "+array[j] +" You");
j++;
if(j== array.length-1) j=0;
start();
.start();
解决这个问题的方法很简单。
【讨论】:
【参考方案8】:我将 Timer 抽象为一个单独的类:
Timer.java
import android.os.Handler;
public class Timer
IAction action;
Handler timerHandler = new Handler();
int delayMS = 1000;
public Timer(IAction action, int delayMS)
this.action = action;
this.delayMS = delayMS;
public Timer(IAction action)
this(action, 1000);
public Timer()
this(null);
Runnable timerRunnable = new Runnable()
@Override
public void run()
if (action != null)
action.Task();
timerHandler.postDelayed(this, delayMS);
;
public void start()
timerHandler.postDelayed(timerRunnable, 0);
public void stop()
timerHandler.removeCallbacks(timerRunnable);
并从Timer
类中提取主要操作为
IAction.java
public interface IAction
void Task();
我就是这样使用它的:
MainActivity.java
public class MainActivity extends Activity implements IAction
...
Timer timerClass;
@Override
protected void onCreate(Bundle savedInstanceState)
...
timerClass = new Timer(this,1000);
timerClass.start();
...
...
int i = 1;
@Override
public void Task()
runOnUiThread(new Runnable()
@Override
public void run()
timer.setText(i + "");
i++;
);
...
我希望这会有所帮助??
【讨论】:
【参考方案9】:如果只想将倒计时安排到未来的某个时间,并在此期间定期通知,您可以使用自 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();
【讨论】:
CountDownTimer 只有在您知道您希望它在多次执行后消失时才有意义。这不是典型的,也不是特别灵活的方法。更常见的是永远重复的计时器(当不再需要时取消),或者运行一次的处理程序,如果再次需要,则重新启动。查看其他答案。 你完全正确。从类名来看,它提供了一个倒计时计时器,直到完成,当然它在其实现中使用了 Handler。 如何也显示毫秒?格式为SS:MiMi
?谢谢
这个答案正是我想要的【参考方案10】:
这是一些简单的计时器代码:
Timer timer = new Timer();
TimerTask t = new TimerTask()
@Override
public void run()
System.out.println("1");
;
timer.scheduleAtFixedRate(t,1000,1000);
【讨论】:
如果我们希望它只在 04:00 使用 Timer 对象运行呢?【参考方案11】:因为这个问题仍然吸引了很多谷歌搜索的用户(关于Android计时器)我想插入我的两个硬币。
首先,Timer 类将在 Java 9 (read the accepted answer) 中被弃用。
official 建议的方法是使用ScheduledThreadPoolExecutor,它更有效且功能更丰富,可以另外安排命令在给定延迟后运行,或定期执行。此外,它还为 ThreadPoolExecutor 提供了额外的灵活性和功能。
这是一个使用简单功能的示例。
创建执行器服务:
final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
只需安排您可运行的时间:
final Future<?> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
您现在可以使用future
取消任务或检查它是否已完成,例如:
future.isDone();
希望您会发现这对于在 Android 中创建任务很有用。
完整示例:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Future<?> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
if (sampleFutureTimer.isDone())
// Do something which will save world.
【讨论】:
【参考方案12】:如果你已经有时间差了。
public class Timer
private float lastFrameChanged;
private float frameDuration;
private Runnable r;
public Timer(float frameDuration, Runnable r)
this.frameDuration = frameDuration;
this.lastFrameChanged = 0;
this.r = r;
public void update(float dt)
lastFrameChanged += dt;
if (lastFrameChanged > frameDuration)
lastFrameChanged = 0;
r.run();
【讨论】:
【参考方案13】:您希望您的 UI 更新发生在已经存在的 UI 线程中。
最好的方法是使用一个使用 postDelayed 的 Handler 在延迟后运行一个 Runnable(每次运行都安排下一次);使用 removeCallbacks 清除回调。
您已经找对地方了,所以再看一遍,或许可以弄清楚为什么该代码示例不是您想要的。 (另请参阅Updating the UI from a Timer 上的相同文章)。
【讨论】:
很遗憾,您的链接已失效。我无法快速找到正确的文章。 工作link here【参考方案14】:我认为你可以用 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
);
然后像这样取消:
timerSubscribe.unsubscribe();
接收定时器http://reactivex.io/documentation/operators/timer.html
【讨论】:
【参考方案15】:你也可以使用动画师:
int secondsToRun = 999;
ValueAnimator timer = ValueAnimator.ofInt(secondsToRun);
timer.setDuration(secondsToRun * 1000).setInterpolator(new LinearInterpolator());
timer.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
@Override
public void onAnimationUpdate(ValueAnimator animation)
int elapsedSeconds = (int) animation.getAnimatedValue();
int minutes = elapsedSeconds / 60;
int seconds = elapsedSeconds % 60;
textView.setText(String.format("%d:%02d", minutes, seconds));
);
timer.start();
【讨论】:
【参考方案16】:import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity
CheckBox optSingleShot;
Button btnStart, btnCancel;
TextView textCounter;
Timer timer;
MyTimerTask myTimerTask;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
optSingleShot = (CheckBox)findViewById(R.id.singleshot);
btnStart = (Button)findViewById(R.id.start);
btnCancel = (Button)findViewById(R.id.cancel);
textCounter = (TextView)findViewById(R.id.counter);
btnStart.setOnClickListener(new OnClickListener()
@Override
public void onClick(View arg0)
if(timer != null)
timer.cancel();
//re-schedule timer here
//otherwise, IllegalStateException of
//"TimerTask is scheduled already"
//will be thrown
timer = new Timer();
myTimerTask = new MyTimerTask();
if(optSingleShot.isChecked())
//singleshot delay 1000 ms
timer.schedule(myTimerTask, 1000);
else
//delay 1000ms, repeat in 5000ms
timer.schedule(myTimerTask, 1000, 5000);
);
btnCancel.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
if (timer!=null)
timer.cancel();
timer = null;
);
class MyTimerTask extends TimerTask
@Override
public void run()
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
final String strDate = simpleDateFormat.format(calendar.getTime());
runOnUiThread(new Runnable()
@Override
public void run()
textCounter.setText(strDate);
);
.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:layout_
android:layout_
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<CheckBox
android:id="@+id/singleshot"
android:layout_
android:layout_
android:text="Single Shot"/>
【讨论】:
我看到你在最初的问题和答案几年后添加了这个。请添加有关此答案与已经存在的其他答案的比较的解释。您为什么要添加另一个 - 有什么好处/什么时候有用/您在其他答案中看到了什么缺点? 我只是分享一个代码,它用不同的方法做同样的工作。但是每当您想更新任何视图的数据时。您必须使用处理程序。因为很多时候我注意到使用 timertask 更新视图不起作用.. @Dave.B 方法对我来说更正确。【参考方案17】:好的,因为这还没有被清除,但有 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");
【讨论】:
@Dave.B,谢谢你的好例子。与您概述的其他方法相比,使用一种方法有什么优点/缺点吗? @Gautam 我相信上述所有方法的性能都差不多。我个人更喜欢上面描述的带有 run Runnable 和 h2 Handler 的处理程序方法,因为它是 android 开发者网站规定的一种,在我看来也是最优雅的。 最好将您的首选方法与其余代码分开。就像您可以有一个示例显示您的首选方式,而另一个示例显示替代方法。将所有三种方法放在一起会更难理解发生了什么(特别是对于像我这样的 android 新手)。不过可能要求太多了:) @JesseAldridge 好主意。我继续并仅使用首选方法添加了代码。 @bluesm 老实说,我只是没有考虑过,但是可以。【参考方案18】:很简单! 您创建新计时器。
Timer timer = new Timer();
然后你扩展定时器任务
class UpdateBallTask extends TimerTask
Ball myBall;
public void run()
//calculate the new position of myBall
然后以一定的更新间隔将新任务添加到 Timer
final int FPS = 40;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000/FPS);
免责声明:这不是理想的解决方案。这是使用 Timer 类的解决方案(如 OP 所要求的那样)。在 Android SDK 中,建议使用 Handler 类(在接受的答案中有示例)。
【讨论】:
如果您阅读了上面的帖子,您就会明白为什么这不是一个理想的解决方案 当然。 OP想用TimerTask来做,我不建议在游戏中使用。 嗯? OP 没有指定如何他们希望它完成。他们链接到一篇使用 TimerTask 的文章,但他们没有要求这样做。 帮了很多忙,谢谢@fiction 很好的答案,简单易懂。【参考方案19】:这是一个简单可靠的方法...
将以下代码放入您的 Activity 中,当您的 Activity 处于“恢复”状态时,tick() 方法将在 UI 线程中每秒调用一次。当然,你可以改变 tick() 方法来做你想做的事,或者增加或减少被调用的频率。
@Override
public void onPause()
_handler = null;
super.onPause();
private Handler _handler;
@Override
public void onResume()
super.onResume();
_handler = new Handler();
Runnable r = new Runnable()
public void run()
if (_handler == _h0)
tick();
_handler.postDelayed(this, 1000);
private final Handler _h0 = _handler;
;
r.run();
private void tick()
System.out.println("Tick " + System.currentTimeMillis());
如果您的活动在滴答期内暂停和恢复,则需要“_h0=_handler”代码以避免两个计时器同时运行。
【讨论】:
为什么用这种尴尬的_h0
方法,而不是像其他人一样在onPause
中使用removeCallbacks
?【参考方案20】:
他是更简单的解决方案,在我的应用中运行良好。
public class MyActivity extends Acitivity
TextView myTextView;
boolean someCondition=true;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
myTextView = (TextView) findViewById(R.id.refreshing_field);
//starting our task which update textview every 1000 ms
new RefreshTask().execute();
//class which updates our textview every second
class RefreshTask extends AsyncTask
@Override
protected void onProgressUpdate(Object... values)
super.onProgressUpdate(values);
String text = String.valueOf(System.currentTimeMillis());
myTextView.setText(text);
@Override
protected Object doInBackground(Object... params)
while(someCondition)
try
//sleep for 1s in background...
Thread.sleep(1000);
//and update textview in ui thread
publishProgress();
catch (InterruptedException e)
e.printStackTrace();
;
return null;
【讨论】:
【参考方案21】:如果有人感兴趣,我开始尝试创建一个标准对象以在活动 UI 线程上运行。似乎工作正常。欢迎评论。我希望它可以在布局设计器中作为组件拖到 Activity 上。简直不敢相信这样的东西还不存在。
package com.example.util.timer;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
public class ActivityTimer
private Activity m_Activity;
private boolean m_Enabled;
private Timer m_Timer;
private long m_Delay;
private long m_Period;
private ActivityTimerListener m_Listener;
private ActivityTimer _self;
private boolean m_FireOnce;
public ActivityTimer()
m_Delay = 0;
m_Period = 100;
m_Listener = null;
m_FireOnce = false;
_self = this;
public boolean isEnabled()
return m_Enabled;
public void setEnabled(boolean enabled)
if (m_Enabled == enabled)
return;
// Disable any existing timer before we enable a new one
Disable();
if (enabled)
Enable();
private void Enable()
if (m_Enabled)
return;
m_Enabled = true;
m_Timer = new Timer();
if (m_FireOnce)
m_Timer.schedule(new TimerTask()
@Override
public void run()
OnTick();
, m_Delay);
else
m_Timer.schedule(new TimerTask()
@Override
public void run()
OnTick();
, m_Delay, m_Period);
private void Disable()
if (!m_Enabled)
return;
m_Enabled = false;
if (m_Timer == null)
return;
m_Timer.cancel();
m_Timer.purge();
m_Timer = null;
private void OnTick()
if (m_Activity != null && m_Listener != null)
m_Activity.runOnUiThread(new Runnable()
@Override
public void run()
m_Listener.OnTimerTick(m_Activity, _self);
);
if (m_FireOnce)
Disable();
public long getDelay()
return m_Delay;
public void setDelay(long delay)
m_Delay = delay;
public long getPeriod()
return m_Period;
public void setPeriod(long period)
if (m_Period == period)
return;
m_Period = period;
public Activity getActivity()
return m_Activity;
public void setActivity(Activity activity)
if (m_Activity == activity)
return;
m_Activity = activity;
public ActivityTimerListener getActionListener()
return m_Listener;
public void setActionListener(ActivityTimerListener listener)
m_Listener = listener;
public void start()
if (m_Enabled)
return;
Enable();
public boolean isFireOnlyOnce()
return m_FireOnce;
public void setFireOnlyOnce(boolean fireOnce)
m_FireOnce = fireOnce;
在活动中,我有这个onStart:
@Override
protected void onStart()
super.onStart();
m_Timer = new ActivityTimer();
m_Timer.setFireOnlyOnce(true);
m_Timer.setActivity(this);
m_Timer.setActionListener(this);
m_Timer.setDelay(3000);
m_Timer.start();
【讨论】:
老兄 ActivityTimerListener 有什么问题?我的 ADT Bundle 说没有这个类。【参考方案22】:void method(boolean u,int max)
uu=u;
maxi=max;
if (uu==true)
CountDownTimer uy = new CountDownTimer(maxi, 1000)
public void onFinish()
text.setText("Finish");
@Override
public void onTick(long l)
String currentTimeString=DateFormat.getTimeInstance().format(new Date());
text.setText(currentTimeString);
.start();
elsetext.setText("Stop ");
【讨论】:
也许一些代码缩进和代码解释会有用。【参考方案23】:如果您还需要在 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
;
【讨论】:
为了完整起见,您可能会提到如何停止计时器,并可能重新启动它。 (我在这里找到了必要的信息:***.com/questions/11550561/…) 有什么理由不能直接从 TimerTask 运行方法调用 runOnUIThread 吗?似乎工作正常并删除了另一层嵌套。 当然,理解所有步骤只是一种教学方法。我建议这个标准有一个可读的代码。【参考方案24】:您需要创建一个线程来处理更新循环并使用它来更新文本区域。但棘手的部分是只有主线程才能真正修改 ui,因此更新循环线程需要向主线程发出信号以进行更新。这是使用 Handler 完成的。
查看此链接:http://developer.android.com/guide/topics/ui/dialogs.html# 单击标题为“带有第二个线程的示例 ProgressDialog”的部分。这是您需要做的一个示例,除了使用进度对话框而不是文本字段。
【讨论】:
不要这样做。有一个简单的计时器类可以为您完成这一切。而这个问题与progressdialogs,或者根本就没有对话。 您是否查看了我发布的链接部分,或者您是否只是看到了对话框一词并假设?那里的代码是 100% 相关的。另外仅供参考,如果您使用计时器,您仍在创建一个线程来处理更新循环。您仍然需要按照我发布的链接中的说明使用处理程序。 很遗憾,链接页面不再包含标题提及的部分。链接到代码时,应始终将键 sn-p 直接包含在您的答案中。以上是关于如何在android中设置计时器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中设置定时器来定期更新 API 数据