【问题标题】:Android: execute code in regular intervalsAndroid:定期执行代码
【发布时间】:2018-07-15 05:31:07
【问题描述】:

我需要定期执行一些代码(连接到服务器并每分钟从 MySQL 数据库中提取数据)。为此,我有一个 Sync 类:

public class Sync {

    static private Handler handler = new Handler();
    Runnable task;

    public Sync(Runnable task, long time) {
        this.task = task;
        handler.removeCallbacks(task);
        handler.postDelayed(task, time);
    }
}

在我的活动中,我有:

public void onCreate(Bundle savedInstanceState) {
    ...
    Sync sync = new Sync(call,60*1000);
    ...
}

final private Runnable call = new Runnable() {
    public void run() {
    //This is where my sync code will be, but for testing purposes I only have a Log statement
    Log.v("test","this will run every minute");
    }
};

我已经尝试过用更短的时间进行测试,但它只运行一次。当它第一次记录消息时,它也是最后一次。有谁看到我在这里做错了什么?谢谢!

【问题讨论】:

  • ScheduleWithFixedDelay 来自 ScheduledThreadPoolExecutor 是另一种选择。

标签: android multithreading


【解决方案1】:

您可以使用以下代码执行此操作, 希望对您有所帮助!

final Handler handler = new Handler(); 
Runnable runnable = new Runnable() { 

    @Override 
    public void run() { 
        try{
            //do your code here
        }
        catch (Exception e) {
            // TODO: handle exception
        }
        finally{
            //also call the same runnable to call it at regular interval
            handler.postDelayed(this, 1000); 
        }
    } 
}; 

//runnable must be execute once
handler.post(runnable);

【讨论】:

  • 是的,这就是我要说的。 AlarmManager 比较重,需要处理 Intent 来触发 Runnable。如果要走的话,让你的 Runnable 在最后重新发布。您应该使用 try-finally 将您的代码包装在 Runnable 中,并在 finally 部分重新发布 Runnable,以确保它永远不会被跳过。
  • 我觉得handler.postDelayed(this, 1000);应该只在finally部分(而不是try块的末尾),否则会发两次。
  • @amram99 您的编辑被其他人拒绝,但我发现它是正确的,因此按照您的建议进行了更新。帕尔马亚 感谢您的评论。
  • 虽然这个答案在回答时是有效的。如果您需要以特定间隔获取数据,您现在应该使用 Firebase Job Dispatcher。原因之一是它可以帮助您的用户节省电池电量(取决于您设置的参数),并且您无需担心您的服务在 Android O+ 上的操作系统在后台被杀死
【解决方案2】:

首先你必须全局声明处理程序 其次,您必须在 runnable 中再次使用 post Delay 方法才能再次触发它。

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Sync sync = new Sync(call,60*1000);

    }
    final private Runnable call = new Runnable() {
        public void run() {
        //This is where my sync code will be, but for testing purposes I only have a Log statement
        Log.v("test","this will run every minute");
        handler.postDelayed(call,60*1000);
        }
    };
    public final Handler handler = new Handler();
    public class Sync {


        Runnable task;

        public Sync(Runnable task, long time) {
            this.task = task;
            handler.removeCallbacks(task);
            handler.postDelayed(task, time);
        }
    }


}

【讨论】:

    【解决方案3】:

    handler.postDelayed(task, time); 只会执行一次,如果您希望代码定期触发,我建议使用 TimerTimerTask 而不是 HandlerRunnable

    TimerTasks 可以设置为运行一次、每 x 秒运行一次,或者以固定周期运行,例如x 秒 - 不管上次运行所花费的时间。

    【讨论】:

      【解决方案4】:
            private void doSomethingRepeatedly() {
            timer.scheduleAtFixedRate( new TimerTask() {
                  public void run() {
      
                        try{
      
                         //Your code
      
                        }
                        catch (Exception e) {
                            // TODO: handle exception
                        }
      
                   }
                  }, 0, 10000);
                           }
      

      【讨论】:

        【解决方案5】:

        另一种方式,使用 ScheduledExecutorService 的scheduleAtFixedRate

        private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        
        public void beepEvery10Seconds() {
             final Runnable beeper = new Runnable() {
               public void run() { System.out.println("beep"); }
             };
             final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, 0, 10, SECONDS);
        }
        

        【讨论】:

          猜你喜欢
          • 2016-11-10
          • 2014-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-23
          • 1970-01-01
          相关资源
          最近更新 更多