安排Android中的重复执行任务
我正在设计一个应用程序,只要应用程序处于前台,它就会重复发送状态到专用服务器。
在我通过网络进行的搜索中,我看到了一些不同的方法,并想知道做这件事的最好方法是什么。
安排服务器调用的最佳方式是什么?
我看到的选项是:
定时器。
的ScheduledThreadPoolExecutor。
服务。
BroadcastReciever与AlarmManager。
你怎么看?
编辑:
我需要的原因是基于聊天的应用程序将所有用户操作发送到远程服务器。
即用户正在输入消息,用户正在阅读消息,用户在线,用户正在离线等。
这意味着每隔一段时间,我都需要向服务器发送我正在做的事情,因为我与其他人打开了一个聊天室,他们需要知道我在做什么。
与whatsapp消息反馈机制类似:
编辑#2:
现在应该几乎总是通过JobScheduler
API(或针对较低API的FirebaseJobDispatcher
)安排定期任务,以防止电池耗尽问题,这可以在Android培训的生命周期部分中阅读
我不确定,但根据我的知识,我分享了我的观点。 如果我错了,我总是接受最好的答案。
报警管理器
只要警报接收器的onReceive()
方法正在执行,警报管理器就会保持一个CPU唤醒锁。 这可以保证手机在您完成广播处理之前不会睡眠。 一旦onReceive()
返回,警报管理器就释放这个唤醒锁。 这意味着只要您的onReceive()
方法完成,手机会在某些情况下进入休眠状态。 如果您的警报接收器调用了Context.startService()
,则在请求的服务启动之前,手机可能会睡眠。 为了防止这种情况发生,您的BroadcastReceiver
和Service
需要实施一个单独的唤醒锁定策略,以确保手机继续运行,直到服务可用。
注意:警报管理器适用于希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行。 对于正常的定时操作(滴答,超时等),使用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
来解决。 所以这不是最好的选择
ScheduledThreadPoolExecutor 。
您可以使用java.util.Timer
或ScheduledThreadPoolExecutor
(首选)来安排在后台线程上定期执行的操作。
以下是使用后者的示例:
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
// call service
}
}, 0, 10, TimeUnit.MINUTES);
所以我更喜欢ScheduledExecutorService
但是请想一想,如果更新将在应用程序运行时发生,则可以使用Timer
,如其他答案中的建议或更新的ScheduledThreadPoolExecutor
。 如果您的应用程序即使在未运行时也会更新,您应该使用AlarmManager
。
警报管理器适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行。
请注意,如果您计划在应用程序关闭时进行更新,则每十分钟一次就会频繁发生,因此可能会耗费太多电量。
计时器
正如javadocs中所提到的,您最好使用ScheduledThreadPoolExecutor。
的ScheduledThreadPoolExecutor
当你的用例需要多个工作线程并且休眠间隔很小时使用这个类。 多么小 ? 那么,我会说大约15分钟。 AlarmManager
开始调度间隔,似乎表明对于较小的睡眠间隔,可以使用此类。 我没有数据来支持最后的声明。 这是一种预感。
服务
您的服务可以随时由VM关闭。 不要将服务用于重复性任务。 重复执行的任务可以启动服务,这完全是另一回事。
BroadcastReciever与AlarmManager
对于更长的睡眠间隔(> 15分钟),这是要走的路。 AlarmManager
已经有了常量( AlarmManager.INTERVAL_DAY
),表明它可以在最初被调度后几天触发任务。 它也可以唤醒CPU来运行你的代码。
您应该根据您的时间和工作线程需求使用这些解决方案之一。
我意识到这是一个古老的问题,已经得到解答,但这可以帮助某人。 在你的activity
private ScheduledExecutorService scheduleTaskExecutor;
在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.
链接地址: http://www.djcxy.com/p/6637.html