使用Java方式:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
或android(Android的处理程序)中有更好的方法吗?
#1 楼
通过java.util.Timer和java.util.TimerTask使用计时器的标准Java方法在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)
对其进行调度。#2 楼
是的,可以使用java的计时器,但是由于这个问题要求更好的方法(针对移动设备)。为了StackOverflow:
由于Timer创建了一个新线程,因此它可能被认为很重, >如果您需要获得的只是在活动运行时回调,则可以将Handler与
Runnable结合使用:
注意,如果要从另一个线程在UI线程中运行一段代码,则可以使用此方法。
如果您的活动未运行,但仍需要回电,则可以使用AlarmManager
评论
更新了链接,谈论谷歌在维护链接方面遇到麻烦。
–塞缪尔
2012年7月10日在1:17
2007年的这篇文章-并不是说这是错误的,但是如果这篇移动文章的历史超过3年,我总是会怀疑。事情变化很快。
– StackOverflowed
2012-09-22 13:13
如果您可以在答案中引用链接的要点,则它更像StackOverflow。
–n611x007
2013年9月30日7:56在
@naxa,我花了两美分使此响应更像StackOverflow。
–塞缪尔
13-10-11在8:14
请注意,导入android.os.Handler而不是java.util.logging
–阿里·布迪尔(Ali Bdeir)
16-09-21在17:25
#3 楼
如我所见,java.util.Timer是实现计时器最常用的工具。对于重复的任务:对于单次运行任务,
new Timer().scheduleAtFixedRate(task, after, interval);
任务是初次执行后要执行的方法
(间隔重复执行的时间)
评论
我将添加时间以毫秒为单位
– Uri
2012-12-27 3:40
ScheduleAtFixedRate的Android开发文档
–n611x007
2013年9月30日在7:51
task可能是您的类的实例,该类继承自java.util.TimerTask并覆盖void run()。
–n611x007
13-09-30在7:54
如此多的投票。你可以做到这一点。但是@Samuel描述了更好的方法。有关原因,请参见他的“此处解释了哪些内容”链接。另外,无法从Timer线程更新UI!并在其他线程中查看以下基于其他处理程序的答案:(简单)stackoverflow.com/a/6702767/199364,或(显示各种替代方案)stackoverflow.com/a/4598737/199364
–ToolmakerSteve
2014年9月12日16:38
@quemeful,因为它并不总是与便利有关,而是与代码质量和效率有关。与使用处理程序相比,这种方式使用更多资源
–深入
19年7月1日在7:53
#4 楼
希望这一功能对您有所帮助,并且可以减少实施工作。Android CountDownTimer类
例如
#5 楼
可能是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();
或
方法2 ::
设置计时器
添加一个名为int的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);
进入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;
}
});
#6 楼
这是情况。Android文档建议您使用AlarmManager注册一个Intent,如果您的应用程序可能未运行,则该Intent将在指定的时间触发。
否则,您应该使用Handler。
注意:警报管理器用于
,如果您想让您的
应用程序代码在特定的特定位置运行
时间,即使您的应用程序当前未在运行。对于正常定时
操作(滴答声,超时等),
使用Handler更容易,更有效。
#7 楼
我们要开始了。我们需要两个类。我正在发布一个代码,该代码每5秒钟(5000毫秒)后会更改移动音频配置文件... br />
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();
}
}
#8 楼
我是Android新手,但这是我根据上述答案创建的计时器类。它适用于我的应用程序,但我欢迎任何建议。用法示例:
...{
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);
}
};
}
#9 楼
我正在使用处理程序并且可运行以创建计时器。我将其包装在一个抽象类中。只需派生/实现它,就可以了: 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()
移到上方一行。#10 楼
我相信在android上执行此操作的方法是您需要运行后台服务。在该后台应用程序中,创建计时器。当计时器“滴答”(设置您要等待的时间间隔)时,启动您要开始的活动。http://developer.android.com/guide/topics/ basics.html(<-本文介绍了活动,服务,意图和Android开发的其他核心基础之间的关系)
#11 楼
我曾经使用(Timer
,TimerTask
)和Handler
定期启动(耗时的)任务。现在,我将整个切换到RxJava。 RxJava提供了Observable.timer
,它更简单,更不易出错,易于使用。public class BetterTimerFragment extends Fragment {
public static final String TAG = "BetterTimer";
private TextView timeView;
private Subscription timerSubscription;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_timer, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
timeView = (TextView) view.findViewById(R.id.timeView);
}
@Override
public void onResume() {
super.onResume();
// Right after the app is visible to users, delay 2 seconds
// then kick off a (heavy) task every 10 seconds.
timerSubscription = Observable.timer(2, 10, TimeUnit.SECONDS)
.map(new Func1<Long, String>() {
@Override
public String call(Long unused) {
// TODO: Probably do time-consuming work here.
// This runs on a different thread than the main thread.
return "Time: " + System.currentTimeMillis();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String timeText) {
// The result will then be propagated back to the main thread.
timeView.setText(timeText);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Log.e(TAG, throwable.getMessage(), throwable);
}
});
}
@Override
public void onPause() {
super.onPause();
// Don't kick off tasks when the app gets invisible.
timerSubscription.unsubscribe();
}
}
#12 楼
对于计时操作,应使用Handler。如果需要运行后台服务,AlarmManager是解决之道。
#13 楼
此示例启动在Kotlin中销毁的计时器unitlprivate lateinit var timerTask: TimerTask
timerTask = object : TimerTask() {
override fun run() {
Log.d("KTZ", "$minutes:$seconds");
timeRecordingLiveData.postValue("$minutes:$seconds")
seconds += 1;
if (seconds == 60) {
Log.d("KTZ", "$minutes:$seconds");
timeRecordingLiveData.postValue("$minutes:$seconds")
seconds = 0;
minutes += 1;
}
}
}
将计时器任务取消在onDestroy()中
评论
这是在Android中处理错误的方法。在android中,您想使用Alarm Manager(developer.android.com/reference/android/app/AlarmManager.html)来运行将来的任务。
–库尔蒂斯·努斯鲍姆(Kurtis Nusbaum)
2011年10月15日下午4:16
@Kurtis Nusbaum问题没有说任务将来有多远。
–克里斯托弗·佩里(Christopher Perry)
2011年11月5日,晚上7:25
@KurtisNusbaum不一定是正确的,它取决于上下文。 AlarmManager上的文档说:“注意:Alarm Manager适用于希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未在运行。对于正常的计时操作(滴答声,超时等)使用Handler更容易,效率也更高。”
–克里斯托弗·佩里(Christopher Perry)
2011-11-5 18:42
@Scienceprodigy啊,我明白了。很公平。
–库尔蒂斯·努斯鲍姆(Kurtis Nusbaum)
11年5月5日在19:07
仅在应用程序获取了唤醒锁后,使用Handler调度任务的方法才是可靠的,因此,您可以确保电话不会进入睡眠状态。如果电话确实进入了睡眠状态,则sendMessageDelayed和sendMessageAtTime将不起作用。因此,在那种情况下,AlarmManager将是可靠的选择。
–crazyaboutliv
2012年1月27日21:59