我正在设计一个应用程序,它有一个经常性的任务,即只要应用程序处于前台,就可以将状态发送到一个专用服务器。
在我的网上搜索中,我看到了几种不同的方法,我想知道什么是最好的方法。
安排服务器调用的最佳方法是什么?
我看到的选项是:
>
定时器。
ScheduledThreadPoolExecutor.
服务。
带有AlarmManager的BroadcastReciever。
你的意见呢?
编辑:
我之所以需要这是因为一个基于聊天的应用程序,它将所有用户操作发送到远程服务器。
即。用户正在键入消息、用户正在阅读消息、用户正在联机、用户正在脱机等。
这意味着每隔一段时间,我需要发送服务器我在做什么,因为我和其他人开了一个聊天室,他们需要知道我在做什么。
编辑#2:
定期任务现在应该几乎总是通过JobScheduler
API(或FireBaseJobDispatcher
)调度,以防止电池耗尽问题,这可以在Android培训的vitals部分中读到
编辑#3:
FirebaseJobDispatcher已被弃用,并被Workmanager取代,Workmanager还包含了JobScheduler的功能。
我知道这是一个老问题,已经被回答了,但这可以帮助一些人。在您的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.
正如在javadocs中提到的,最好使用ScheduledThreadPoolExecutor。
当您的用例需要多个工作线程并且睡眠间隔很小时,请使用此类。多小?我想大概15分钟吧。AlarmManager
此时启动计划间隔,似乎建议对于较小的睡眠间隔可以使用此类。我没有数据支持上一个声明。这是一种预感。
您的服务可以随时被虚拟机关闭。不要将服务用于定期任务。一个重复任务可以启动一个服务,这完全是另一回事。
对于较长的睡眠间隔(>15分钟),这是一种方法。alarmmanager
已具有常量(alarmmanager.interval_day
),这表明它可以在最初计划后几天触发任务。它还可以唤醒CPU来运行你的代码。
您应该根据您的时间和工作线程需要使用这些解决方案之一。
我不确定,但据我所知,我同意我的观点。如果我错了,我总是接受最好的回答。
警报管理器
只要警报接收器的onreceive()
方法正在执行,警报管理器就会持有CPU唤醒锁。这保证了在您处理完广播之前,电话不会休眠。一旦onreceive()
返回,警报管理器将释放此唤醒锁。这意味着在某些情况下,只要onreceive()
方法完成,电话就会立即休眠。如果您的警报接收器调用了context.startservice()
,则电话可能会在请求的服务启动之前休眠。为了防止这种情况,您的broadcastreceiver
和service
将需要实现单独的唤醒锁定策略,以确保电话继续运行,直到服务可用。
注意:警报管理器适用于希望在特定时间运行应用程序代码的情况,即使应用程序当前未运行。对于正常的定时操作(滴答、超时等),使用处理程序更容易,效率更高。
定时器
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
synchronized public void run() {
\\ here your todo;
}
}, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
计时器
有一些缺点,可通过ScheduledThreadPoolExecutor
解决。所以这不是最好的选择
ScheduledThreadPoolExecutor.
您可以使用java.util.Timer
或ScheduledThreadPoolExecutor
(首选)来调度在后台线程上定期发生的操作。
下面是使用后者的示例:
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate
(new Runnable() {
public void run() {
// call service
}
}, 0, 10, TimeUnit.MINUTES);
因此我更喜欢ScheduleDexecutorService
但是还要考虑到,如果更新将在应用程序运行时发生,则可以使用计时器
(如其他答案中所建议的),或者使用较新的ScheduledThreadPoolExecutor
。如果您的应用程序即使不运行也会更新,那么您应该使用AlarmManager
。
警报管理器适用于希望在特定时间运行应用程序代码的情况,即使应用程序当前未运行。
请注意,如果您计划在关闭应用程序时进行更新,那么每十分钟更新一次是相当频繁的,因此可能会有点太耗电。
Google和Stackoverflow上有很多关于优先级抢占式调度的资料,但是我仍然对优先级抢占式调度内核中无限循环任务的调度感到困惑。让我们考虑以下情况: RTOS启动两个任务< code>T1和< code>T2,优先级分别为< code>50和< code>100。这两项任务看起来都像: 和 据我所知,内核会因为其较高的优先级而调度并因为其较低的优先级而挂起。现在因为是一个无限循环,它永远
浏览器中 JavaScript 的执行流程和 Node.js 中的流程都是基于 事件循环 的。 理解事件循环的工作方式对于代码优化很重要,有时对于正确的架构也很重要。 在本章中,我们首先介绍事件循环工作方式的理论细节,然后介绍该知识的实际应用。 事件循环 事件循环 的概念非常简单。它是一个在 JavaScript 引擎等待任务,执行任务和进入休眠状态等待更多任务这几个状态之间转换的无限循环。 引擎
问题内容: 有没有一种方法可以停止执行无限循环的线程? 问题答案: 是的,您可以将替换(或在逻辑上)。 这样,当任务取消时,循环将终止。 循环看起来像这样: 使用应该是这样的:
我刚刚读完Promises/A规范,偶然发现了术语microtask和macrotask:参见http://promisesaplus.com/#notes 我以前从未听说过这些术语,现在我很好奇会有什么区别? 我已经试图在网上找到一些信息,但我找到的只是w3.org档案馆的这篇文章(这篇文章没有向我解释其中的区别):http://lists.w3.org/Archives/Public/publ
问题内容: 我刚读完Promises / A+规范,偶然发现了术语microtask和macrotask: 我以前从未听说过这些术语,现在我很好奇可能会有什么不同? 鉴于此WHATWG规范,我知道理论上我应该能够自己提取差异。但是我确信,专家的简短解释也可以使其他人受益。 问题答案: 事件循环的 一种解决 方法是从 宏任务队列中 恰好 处理 一个 任务在WHATWG规范中,该队列简称为 任务队列
可以通过设置任务详情页中的周期,实现建立周期性任务。比如“周例会”