如何使用AlarmManager调用特定的类方法?

时间:2019-08-17 04:52:11

标签: android android-asynctask broadcastreceiver alarmmanager android-handler

我想执行一个动作,等待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()

2 个答案:

答案 0 :(得分:2)

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

WorkManager Docs

WorkManager Architecture

WorkmManager CodeLab

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

以上是一个简单的实现,但应该可以带给您总体思路。

答案 1 :(得分:0)

您可以在工作管理器中使用 PeriodicWorkRequest 来运行序列作业。 Work Manager正常运行后台作业,并处理许多情况,例如如果没有Internet连接,电池电量低等情况,则无法运行(它使用 Constraint