是的,Java的计时器可以用,但问题要求更好的方式(针对移动设备)。这个更好的方式在这里有解释。
为了StackOverflow的缘故:
由于Timer会创建一个新线程,因此它可能被视为繁重的操作,
如果你只需要在活动运行时得到回调函数,可以使用Handler与Runnable一起使用:
private final int interval = 1000; // 1 Second
private Handler handler = new Handler();
private Runnable runnable = new Runnable(){
public void run() {
Toast.makeText(MyActivity.this, "C'Mom no hands!", Toast.LENGTH_SHORT).show();
}
};
...
handler.postAtTime(runnable, System.currentTimeMillis()+interval);
handler.postDelayed(runnable, interval);
或者一个Message
private final int EVENT1 = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Event1:
Toast.makeText(MyActivity.this, "Event 1", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(MyActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
break;
}
}
};
...
Message msg = handler.obtainMessage(EVENT1);
handler.sendMessageAtTime(msg, System.currentTimeMillis()+interval);
handler.sendMessageDelayed(msg, interval);
顺便说一下,如果你想从另一个线程运行UI线程的代码,可以使用这种方法。
警告:Handler
的定时器(或其他控制延迟的机制)会在CPU进入深度睡眠时暂停,但一旦CPU被唤醒(从暂停的位置继续),定时器将继续工作。
如果需要即使您的Activity没有运行也能获得回调,则可以使用AlarmManager。
使用标准Java计时器方式,通过java.util.Timer和java.util.TimerTask在Android上可以正常工作,但您应该知道这种方法会创建一个新线程。
您可以考虑使用非常方便的Handler类(android.os.Handler)并通过sendMessageAtTime(android.os.Message, long)
或sendMessageDelayed(android.os.Message, long)
向处理程序发送消息。一旦收到消息,您可以运行所需的任务。第二个选项是创建一个Runnable对象,并通过Handler的函数postAtTime(java.lang.Runnable, long)
或postDelayed(java.lang.Runnable, long)
进行调度。
据我所见,java.util.Timer 是实现计时器最常用的方法。
对于重复任务:
new Timer().scheduleAtFixedRate(task, after, interval);
针对单个任务的一次运行:
new Timer().schedule(task, after);
task 指要执行的方法
在after时间后初始执行
(interval代表重复执行间隔时间)
我希望这个可以帮助你,而且实现起来可能需要的努力会更少, Android CountDownTimer类
例如:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
可能是 计时器概念
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
第二种方法 ::
编程定时器
添加一个名为time的int变量,并将其设置为0。 在MainActivity.java的onCreate函数中添加以下代码。
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
//We must use this function in order to change the text view text
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView tv = (TextView) findViewById(R.id.main_timer_text);
tv.setText(String.valueOf(time));
time += 1;
}
});
开始吧.. 我们需要两个类。我将发布一段代码,该代码每隔5秒(5000毫秒)更改移动音频配置文件...
我们的第一个类
public class ChangeProfileActivityMain extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Timer timer = new Timer();
TimerTask updateProfile = new CustomTimerTask(ChangeProfileActivityMain.this);
timer.scheduleAtFixedRate(updateProfile, 0, 5000);
}
}
我们的第二课
public class CustomTimerTask extends TimerTask {
private AudioManager audioManager;
private Context context;
private Handler mHandler = new Handler();
// Write Custom Constructor to pass Context
public CustomTimerTask(Context con) {
this.context = con;
}
@Override
public void run() {
// TODO Auto-generated method stub
// your code starts here.
// I have used Thread and Handler as we can not show Toast without starting new thread when we are inside a thread.
// As TimePicker has run() thread running., So We must show Toast through Handler.post in a new Thread. Thats how it works in Android..
new Thread(new Runnable() {
@Override
public void run() {
audioManager = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
mHandler.post(new Runnable() {
@Override
public void run() {
if(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(context, "Ringer Mode set to Normal", Toast.LENGTH_SHORT).show();
} else {
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(context, "Ringer Mode set to Silent", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
}
这取决于情况。
Android文档建议,如果您的应用程序可能没有运行,则使用AlarmManager来注册将在指定时间触发的意图。
否则,您应该使用Handler。
注意:Alarm Manager适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行。对于正常的计时操作(如滴答声、超时等),使用Handler更容易,也更高效。
...{
public Handler uiHandler = new Handler();
private Runnable runMethod = new Runnable()
{
public void run()
{
// do something
}
};
timer = new UITimer(handler, runMethod, timeoutSeconds*1000);
timer.start();
}...
public class UITimer
{
private Handler handler;
private Runnable runMethod;
private int intervalMs;
private boolean enabled = false;
private boolean oneTime = false;
public UITimer(Handler handler, Runnable runMethod, int intervalMs)
{
this.handler = handler;
this.runMethod = runMethod;
this.intervalMs = intervalMs;
}
public UITimer(Handler handler, Runnable runMethod, int intervalMs, boolean oneTime)
{
this(handler, runMethod, intervalMs);
this.oneTime = oneTime;
}
public void start()
{
if (enabled)
return;
if (intervalMs < 1)
{
Log.e("timer start", "Invalid interval:" + intervalMs);
return;
}
enabled = true;
handler.postDelayed(timer_tick, intervalMs);
}
public void stop()
{
if (!enabled)
return;
enabled = false;
handler.removeCallbacks(runMethod);
handler.removeCallbacks(timer_tick);
}
public boolean isEnabled()
{
return enabled;
}
private Runnable timer_tick = new Runnable()
{
public void run()
{
if (!enabled)
return;
handler.post(runMethod);
if (oneTime)
{
enabled = false;
return;
}
handler.postDelayed(timer_tick, intervalMs);
}
};
}
我正在使用handler和runnable创建一个计时器。我将它包装在一个抽象类中。只需派生/实现它,你就可以开始了:
public static abstract class SimpleTimer {
abstract void onTimer();
private Runnable runnableCode = null;
private Handler handler = new Handler();
void startDelayed(final int intervalMS, int delayMS) {
runnableCode = new Runnable() {
@Override
public void run() {
handler.postDelayed(runnableCode, intervalMS);
onTimer();
}
};
handler.postDelayed(runnableCode, delayMS);
}
void start(final int intervalMS) {
startDelayed(intervalMS, 0);
}
void stop() {
handler.removeCallbacks(runnableCode);
}
}
handler.postDelayed
- 这将使计时器更加接近预期的时间。但是,在计时器运行太频繁且任务(onTimer()
)太长的情况下,可能会出现重叠。如果您想在任务完成后开始计算intervalMS
,请将onTimer()
调用提前一行。
android.os.Handler
,而不是java.util.logging
。 - Ali Bdeir