我已经创建了时间任务,其中用户想要重复的任务,添加自定义TimeTask run()方法。它成功地重复出现了。
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; import android.content.Intent; public class MainActivity extends Activity { CheckBox optSingleShot; Button btnStart, btnCancel; TextView textCounter; Timer timer; MyTimerTask myTimerTask; int tobeShown = 0 ; @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); tobeShown = 1; 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, 1000); } btnStart.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { Intent i = new Intent(MainActivity.this, ActivityB.class); startActivity(i); /*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, 1000); }*/ }}); btnCancel.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { if (timer!=null){ timer.cancel(); timer = null; } } }); } @Override protected void onResume() { super.onResume(); 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, 1000); } } @Override protected void onPause() { super.onPause(); if (timer!=null){ timer.cancel(); timer = null; } } @Override protected void onStop() { super.onStop(); 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); }}); } }
}
我不确定,但据我所知,我赞同我的看法。如果我错了,我总是接受最好的答案。
的 报警管理器 强>
只要报警接收器,报警管理器就会保持CPU唤醒锁定 onReceive() 方法正在执行。这可以保证在您完成广播处理之后手机不会睡眠。一旦 onReceive() 返回时,Alarm Manager释放此唤醒锁定。这意味着手机在某些情况下会尽快睡觉 onReceive() 方法完成。如果你的报警接收器叫 Context.startService() ,在启动所请求的服务之前,手机可能会休眠。为了防止这种情况,你的 BroadcastReceiver 和 Service 将需要实施单独的唤醒锁定策略,以确保手机继续运行,直到服务可用。
onReceive()
Context.startService()
BroadcastReceiver
Service
注意:Alarm Manager适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行也是如此。对于正常的计时操作(刻度,超时等),使用Handler更容易,也更有效。
的 计时器 强>
timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { synchronized public void run() { \\ here your todo; } }}, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
Timer 有一些弊端可以解决 ScheduledThreadPoolExecutor 。所以这不是最好的选择
Timer
ScheduledThreadPoolExecutor
的 的ScheduledThreadPoolExecutor 强> 。
您可以使用 java.util.Timer 要么 ScheduledThreadPoolExecutor (首选)安排在后台线程上定期执行操作。
java.util.Timer
以下是使用后者的示例:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate (new Runnable() { public void run() { // call service } }, 0, 10, TimeUnit.MINUTES);
所以我更喜欢 ScheduledExecutorService
ScheduledExecutorService
但是,请考虑一下,如果在应用程序运行时进行更新,则可以使用 Timer ,如其他答案所示,或更新的 ScheduledThreadPoolExecutor 。 如果你的应用程序即使没有运行也会更新,你应该使用 AlarmManager 。
AlarmManager
Alarm Manager适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行也是如此。
请注意,如果您计划在应用程序关闭时进行更新,则每十分钟一次是非常频繁的,因此可能有点过于耗电。
如上所述 的javadoc 你最好使用ScheduledThreadPoolExecutor。
当您的用例需要多个工作线程且睡眠间隔很小时,请使用此类。多么小 ?好吧,我说约15分钟。该 AlarmManager 此时开始计划间隔,似乎表明对于较小的睡眠间隔,可以使用此类。我没有数据支持最后一个声明。这是一种预感。
您的服务可以随时由VM关闭。不要将服务用于重复性任务。一个经常性的任务可以 开始 服务,完全是另一回事。
对于更长的睡眠间隔(> 15分钟),这是要走的路。 AlarmManager 已经有常数( AlarmManager.INTERVAL_DAY )建议它可以在最初安排几天后触发任务。它还可以唤醒CPU以运行代码。
AlarmManager.INTERVAL_DAY
您应该根据您的时间和工作线程需求使用其中一种解决方案。
引用 调度重复警报 - 理解权衡 文档:
在应用程序生命周期之外触发操作的常见方案是将数据与服务器同步。在这种情况下,您可能会想要使用重复警报。但是,如果您拥有托管应用数据的服务器,那么将Google Cloud Messaging(GCM)与同步适配器结合使用是比AlarmManager更好的解决方案。同步适配器为您提供与AlarmManager相同的调度选项,但它为您提供了更大的灵活性。
因此,基于此,调度服务器调用的最佳方法是使用 Google云消息传递(GCM) 和这个结合 同步适配器 。
我意识到这是一个古老的问题,已经得到了回答,但这可以帮助某人。 在你的 activity
activity
private ScheduledExecutorService scheduleTaskExecutor;
在 onCreate
onCreate
scheduleTaskExecutor = Executors.newScheduledThreadPool(5); //Schedule a task to run every 5 seconds (or however long you want) scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() { @Override public void run() { // Do stuff here! runOnUiThread(new Runnable() { @Override public void run() { // Do stuff to update UI here! Toast.makeText(MainActivity.this, "Its been 5 seconds", Toast.LENGTH_SHORT).show(); } }); } }, 0, 5, TimeUnit.SECONDS); // or .MINUTES, .HOURS etc.