Android:定期执行代码

Tom*_*ček 33 multithreading android

我需要定期执行一些代码(连接到服务器并每分钟从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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的活动中我有:

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");
    }
};
Run Code Online (Sandbox Code Playgroud)

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

MKJ*_*ekh 53

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

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

  • 我认为`handler.postDelayed(this,1000);`应该只在finally部分(不在try块的末尾),否则它将被发布两次. (27认同)
  • 是的,这就是我要说的.AlarmManager较重,需要处理Intent才能触发Runnable.如果要走的话,让你的Runnable在最后重新发布.你应该使用try-finally将代码包装在Runnable中,并在finally部分重新发布Runnable,以确保它永远不会被跳过. (2认同)

Man*_*esh 8

首先,你必须全局声明处理程序第二,你必须在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);
        }
    }


}
Run Code Online (Sandbox Code Playgroud)