安排Android中的重复任务

the*_*osh 116 android scheduled-tasks

我正在设计一个应用程序,只要应用程序位于前台,该应用程序就会定期向专用服务器发送状态.

在我通过网络搜索时,我看到了一些不同的方法,并想知道这样做的最佳方法是什么.

安排服务器调用的最佳方法是什么?

我看到的选项是:

  1. 计时器.

  2. ScheduledThreadPoolExecutor.

  3. 服务.

  4. AlarmManager的 BroadcastReciever .

你怎么看?

编辑:
我需要这个的原因是一个基于聊天的应用程序,它将所有用户操作发送到远程服务器.
即用户正在键入消息,用户正在阅读消息,用户在线,用户在线等.

这意味着每隔一段时间,我需要向服务器发送我正在做的事情,因为我和其他人打开聊天室,他们需要知道我在做什么.

与whatsapp消息反馈机制类似: 消息看起来交付

编辑#2:
现在几乎总是通过JobSchedulerAPI(或FirebaseJobDispatcher更低的API)安排重复任务,以防止电池耗尽问题,可以在Android培训的vitals部分阅读

Md *_*lam 162

我不确定,但据我所知,我赞同我的看法.如果我错了,我总是接受最好的答案.

报警管理器

只要警报接收器的onReceive()方法正在执行,警报管理器就会保持CPU唤醒锁定.这可以保证在您完成广播处理之后手机不会睡眠.一旦onReceive()返回后,报警管理器释放该唤醒锁.这意味着手机在某些情况下会在您的onReceive()方法完成后立即进入睡眠状态.如果您的警报接收器被呼叫Context.startService(),则可能在启动所请求的服务之前电话将处于休眠状态.为了防止这种情况,你BroadcastReceiverService需要实现一个单独的唤醒锁定策略,以确保手机继续运行,直到服务可用.

注意:警报管理器适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行也是如此.对于正常的计时操作(刻度,超时等),使用Handler更容易,也更有效.

计时器

timer = new Timer();

    timer.scheduleAtFixedRate(new TimerTask() {

        synchronized public void run() {

            \\ here your todo;
            }

        }}, TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
Run Code Online (Sandbox Code Playgroud)

Timer有一些弊端可以解决ScheduledThreadPoolExecutor.所以这不是最好的选择

ScheduledThreadPoolExecutor.

您可以使用java.util.TimerScheduledThreadPoolExecutor(首选)安排在后台线程上定期执行操作.

以下是使用后者的示例:

ScheduledExecutorService scheduler =
    Executors.newSingleThreadScheduledExecutor();

scheduler.scheduleAtFixedRate
      (new Runnable() {
         public void run() {
            // call service
         }
      }, 0, 10, TimeUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)

所以我更喜欢 ScheduledExecutorService

但另外请注意,如果在应用程序运行时进行更新,您可以使用Timer其他答案中建议的更新版本ScheduledThreadPoolExecutor.如果你的应用程序即使没有运行也会更新,你应该使用AlarmManager.

Alarm Manager适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未运行也是如此.

请注意,如果您计划在应用程序关闭时进行更新,则每十分钟一次是非常频繁的,因此可能有点过于耗电.


Dee*_*ala 30

计时器

正如javadocs中提到的,最好使用ScheduledThreadPoolExecutor.

的ScheduledThreadPoolExecutor

当您的用例需要多个工作线程且睡眠间隔很小时,请使用此类.多么小 ?好吧,我说约15分钟.此时AlarmManager开始计划间隔,似乎表明对于较小的睡眠间隔,可以使用此类.我没有数据支持最后一个声明.这是一种预感.

服务

您的服务可以随时由VM关闭.不要将服务用于重复性任务.重复性任务可以启动服务,这完全是另一回事.

带AlarmManager的BroadcastReciever

对于更长的睡眠间隔(> 15分钟),这是要走的路.AlarmManager已经有constants(AlarmManager.INTERVAL_DAY)表明它可以在最初安排几天后触发任务.它还可以唤醒CPU以运行您的代码.

您应该根据您的时间和工作线程需求使用其中一种解决方案.


Emz*_*zor 13

我意识到这是一个古老的问题,已经得到了回答,但这可以帮助某人.在你的activity

private ScheduledExecutorService scheduleTaskExecutor;
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)