android - 如何使用 AlarmManager 调用特定的类方法?
问题描述
我想执行一个动作,等待 n 秒,执行另一个动作,再次等待,等等(异步)。
首先,我使用 AsyncTask 得到它。问题是即使设备被锁定,我也需要它(因为目标是将订单发送到另一台设备)。
然后我想使用AlarmManager,做这样的事情:
public class MainClass {
private static MainClass instance;
private static Context context;
private MainClass(){}
public static MainClass getInstance(Context context){
MainClass.context = context;
if (instance == null) instance = new MainClass();
return instance;
}
// [...]
private Alarm alarm = null;
private static Worker worker = null ;
private static Handler my_handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
worker.executeNextAction();
}
};
public void start(){
alarm = new Alarm();
worker = new Worker();
worker.executeNextAction();
}
public static class Alarm extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
my_handler.sendMessage(new Message());
}
public void setAlarm(Context context, int seconds)
{
AlarmManager alarm_manager =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Alarm.class);
PendingIntent pending_intent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarm_manager.set(AlarmManager.RTC_WAKEUP, 1000 * seconds, pending_intent);
}
public void cancelAlarm(Context context) { /*[...]*/ }
}
private class Worker {
void executeNextAction() {
// do tasks
alarm.setAlarm(context, duration);
}
// [...]
}
}
这不起作用,因为 worker 在handleMessage()
.
我如何executeNextAction()
从方法中调用onReceive()
方法?
解决方案
WorkManager
是高度可配置的,将允许您创建一个PeriodicWorkRequest
或一个OneTimeWorkRequest
这些保证成功。PeriodicWorkRequest
将在您安排工作以及在计时器中指定时触发。即使应用程序关闭或后台运行,它也会在后台执行。如果您不希望您的任务立即执行,您可以使用 PWR(PeriodicWorkRequest) 和FlexInterval。有关更多信息,请参阅下面的文档。
例如,我创建了两个 PeriodicWorkRequests 来刷新服务并通过更新其令牌保持用户始终登录。当用户验证时PeriodicWorkRequest
创建。就我而言,我不需要它立即触发,因为他们刚刚接收并缓存了此信息,因此我使用了 FlexInterval。当应用程序处于后台或关闭状态时,工作人员会继续每 12 小时刷新一次服务,并每 6 小时刷新一次令牌。它就像一个魅力。
这是一个例子:
构建工作:
override fun beginWork() {
val periodicWorkRequest = PeriodicWorkRequest.Builder(
MyWorker::class.java,
REPEAT_INTERVAL, TimeUnit.MINUTES, // How often work should repeat
// Flex not required.
FLEX_INTERVAL, TimeUnit.MINUTES) // Limits execution into a time window
.setConstraints(
Constraints.Builder().setRequiredNetworkType(
NetworkType.CONNECTED).build())
.addTag(MY_WORKER_TAG)
.build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
MY_UNIQUE_WORK,
ExistingPeriodicWorkPolicy.KEEP,
periodicLoginRequest)
工人:
class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
// DO WORK HERE
Result.success()
} else {
// HANDLE FAILURE HERE
Result.failure()
}
上面是一个简单的实现,但它应该给你一个大致的想法。
推荐阅读
- java - 为什么 java.util.ArrayList 包中的数据数组是私有的?
- python - 创建 Python 循环以查找开始和停止值
- json - golang解组未知的json数据
- ruby-on-rails - 带有 gitlab CI/CD 的 Rails .env
- ios - 广告活动归因,在 iOS 中使用 Firebase Analytics 将广告活动信息发送到 Google 标签管理器
- flutter - 如何在 Flutter Bloc 中进行拉动刷新(LiquidPullToRefresh)时刷新当前页面
- facebook - “请更新您的隐私政策以符合我们的平台条款”我有隐私政策链接
- android - TextView 电子邮件后缀“.com”换行(无需 breakStrategy 即可修复)
- python - Pandas 数据框合并为匹配列提供了奇怪的输出
- r - 在同一张纸上安排 ggplot 时出现错误,包括 grobs