首页 > 解决方案 > 如何使用 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()方法?

标签: androidandroid-asynctaskbroadcastreceiveralarmmanagerandroid-handler

解决方案


WorkManager是高度可配置的,将允许您创建一个PeriodicWorkRequest或一个OneTimeWorkRequest这些保证成功。PeriodicWorkRequest将在您安排工作以及在计时器中指定时触发。即使应用程序关闭或后台运行,它也会在后台执行。如果您不希望您的任务立即执行,您可以使用 PWR(PeriodicWorkRequest) 和FlexInterval。有关更多信息,请参阅下面的文档。

WorkManager 文档

WorkManager 架构

WorkmManager 代码实验室

例如,我创建了两个 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()
        }

上面是一个简单的实现,但它应该给你一个大致的想法。


推荐阅读