如何在android中设置计时器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1877417/
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
How to set a timer in android
提问by n179911
What is the proper way to set a timer in android in order to kick off a task (a function that I create which does not change the UI)? Use this the Java way: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
在 android 中设置计时器以启动任务(我创建的不更改 UI 的功能)的正确方法是什么?使用 Java 方式:http: //docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Or there is a better way in android (android's handler)?
或者在android(android的处理程序)中有更好的方法?
采纳答案by MannyNS
Standard Java way to use timers via java.util.Timerand java.util.TimerTaskworks fine in Android, but you should be aware that this method creates a new thread.
通过java.util.Timer和java.util.TimerTask使用计时器的标准 Java 方法在 Android中运行良好,但您应该知道此方法会创建一个新线程。
You may consider using the very convenient Handlerclass (android.os.Handler) and send messages to the handler via sendMessageAtTime(android.os.Message, long)
or sendMessageDelayed(android.os.Message, long)
. Once you receive a message, you can run desired tasks. Second option would be to create a Runnableobject and schedule it via Handler's functions postAtTime(java.lang.Runnable, long)
or postDelayed(java.lang.Runnable, long)
.
您可以考虑使用非常方便的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)
.
回答by Samuel
yes java's timer can be used, but as the question asks for better way(for mobile). Which is explained Here.
是的,可以使用java 的计时器,但由于问题要求更好的方法(对于移动设备)。这是解释here。
For the sake of StackOverflow:
为了 StackOverflow:
Since Timercreates a new thread it may be considered heavy,
由于Timer创建了一个新线程,因此它可能被认为很重,
if all you need is to get is a call back while the activity is running a Handlercan be used in conjunction with a
如果您只需要在 Activity 运行时获得回调,则Handler可以与
可运行:
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);
or a 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);
on a side note this approach can be used, if you want to run a piece of code in the UI thread from an another thread.
附带说明一下,如果您想从另一个线程在 UI 线程中运行一段代码,则可以使用这种方法。
if you need to get a call back even if your activity is not running then, you can use an AlarmManager
如果即使您的活动没有运行也需要回电,您可以使用AlarmManager
回答by Thizzer
As I have seen it, java.util.Timeris the most used for implementing a timer.
正如我所见,java.util.Timer最常用于实现计时器。
For a repeating task:
对于重复任务:
new Timer().scheduleAtFixedRate(task, after, interval);
For a single run of a task:
对于任务的单次运行:
new Timer().schedule(task, after);
taskbeing the method to be executed
afterthe time to initial execution
(intervalthe time for repeating the execution)
任务是在初始执行时间
之后要执行的方法
(间隔重复执行的时间)
回答by Gaurav Adurkar
I hope this one is helpful and may take less efforts to implement, Android CountDownTimer class
我希望这个是有帮助的,并且可以减少实现, Android CountDownTimer 类
e.g.
例如
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
回答by vkulkarni
Probably Timerconcept
大概 Timerconcept
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();
or
或者
Method 2 ::
方法 2 ::
Program the timer
编程定时器
Add a new variable of int named time. Set it to 0. Add the following code to onCreate function in MainActivity.java.
添加一个名为 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);
Go into the run method and add the following code.
进入run方法并添加以下代码。
//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;
}
});
回答by Timothy Lee Russell
It is situational.
这是视情况而定。
The Android documentation suggests that you should use AlarmManagerto register an Intent that will fire at the specified time if your application may not be running.
Android 文档建议您应该使用AlarmManager注册一个 Intent,如果您的应用程序可能未运行,该 Intent 将在指定时间触发。
Otherwise, you should use Handler.
否则,您应该使用 Handler。
Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
注意:警报管理器适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行。对于正常的计时操作(滴答、超时等),使用 Handler 更容易也更有效。
回答by Rizwan Sohaib
Here we go.. We will need two classes. I am posting a code which changes mobile audio profile after each 5 seconds (5000 mili seconds) ...
来吧.. 我们需要两个类。我发布了一个代码,每 5 秒(5000 毫秒)更改一次移动音频配置文件......
Our 1st Class
我们的第一堂课
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);
}
}
Our 2nd Class
我们的二年级
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();
}
}
回答by user868020
I'm an Android newbie but here is the timer class I created based on the answers above. It works for my app but I welcome any suggestions.
我是 Android 新手,但这是我根据上述答案创建的计时器类。它适用于我的应用程序,但我欢迎任何建议。
Usage example:
用法示例:
...{
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);
}
};
}
回答by elcuco
I am using a handler and runnable to create a timer. I wrapper this in an abstract class. Just derive/implement it and you are good to go:
我正在使用处理程序和 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);
}
}
Note that the handler.postDelayed
is called before the code to be executed - this will make the timer more closed timed as "expected". However in cases were the timer runs to frequently and the task (onTimer()
) is long - there might be overlaps. If you want to start counting intervalMS
after the task is done, move the onTimer()
call a line above.
请注意,在handler.postDelayed
要执行的代码之前调用了 - 这将使计时器更接近于“预期”计时。但是,在计时器频繁运行且任务 ( onTimer()
) 很长的情况下 - 可能会出现重叠。如果您想intervalMS
在任务完成后开始计数,请将onTimer()
呼叫移至上方一行。
回答by Crowe T. Robot
I believe the way to do this on the android is that you need a background service to be running. In that background application, create the timer. When the timer "ticks" (set the interval for how long you want to wait), launch your activity which you want to start.
我相信在 android 上执行此操作的方法是您需要运行后台服务。在该后台应用程序中,创建计时器。当计时器“滴答作响”(设置您要等待的时间间隔)时,启动您要开始的活动。
http://developer.android.com/guide/topics/fundamentals.html(<-- this article explains the relationship between activities, services, intents and other core fundamentals of Android development)
http://developer.android.com/guide/topics/fundamentals.html(<--本文解释了Android开发的Activity、Services、intents等核心基础知识之间的关系)