【问题标题】:How to call a specific class method using AlarmManager?如何使用 AlarmManager 调用特定的类方法?
【发布时间】:2019-12-23 07:03:45
【问题描述】:

我想执行一个动作,等待 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);
        }
        // [...]
    }
}

这不起作用,因为 handleMessage() 中的 worker 将为 null。

如何从onReceive() 方法调用executeNextAction() 方法?

【问题讨论】:

  • 你不应该经常使用 AlarmManager,而是使用 WorkManager,就像@Richard Dapice 解释的那样。
  • 非常感谢,我不知道 WorkManager。阅读更多内容后,我认为使用前台服务对我来说更好(它在后台显示通知),因为如果用户关闭应用程序,我不希望完成工作。这是一个即时工作,每 n 秒修改一次。 developer.android.com/guide/components/servicesandroid-developers.googleblog.com/2018/10/…If the app needs to complete a user-initiated task without deferring even if the user leaves the app or turns off the screen, you should use a Foreground service.

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


【解决方案1】:

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

WorkManager Docs

WorkManager Architecture

WorkmManager CodeLab

例如,我创建了两个 PeriodicWorkRequest 来刷新服务并通过更新其令牌保持用户始终登录。当用户验证时,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()
        }

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

【讨论】:

    【解决方案2】:

    您可以使用 Work Manager 中的 PeriodicWorkRequest 来运行序列作业。工作管理器优雅地运行后台作业并处理许多情况,如没有互联网连接、电池电量不足等情况下不运行(它使用约束

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      相关资源
      最近更新 更多