Android - loop part of the code every 5 seconds
我想每5秒钟开始重复执行两行代码,当我按下启动按钮时结束,并在我按下停止按钮时结束。 我曾尝试过使用TimerTask和Handles,但无法弄清楚该怎么做。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //final int i; final TextView textView = (TextView) findViewById(R.id.textView); final Button START_STOP = (Button) findViewById(R.id.START_STOP); final ImageView random_note = (ImageView) findViewById(R.id.random_note); final int min = 0; final int max = 2; final Integer[] image = { R.drawable.a0, R.drawable.a1,R.drawable.a2 }; START_STOP.setTag(1); START_STOP.setText("START"); START_STOP.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int status = (Integer) v.getTag(); if (status ==1) { textView.setText("Hello"); START_STOP.setText("STOP"); v.setTag(0); final Random random = new Random(); //************************************************************ // I would like to loop next 2 lines of code every 5 seconds.// int i = random.nextInt(2 - 0 + 1) + 0; random_note.setImageResource(image[i]); //************************************************************ } else { textView.setText("Bye"); START_STOP.setText("Let's PLAY!"); v.setTag(1); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } |
在其他答案之一中使用CountDownTimer是实现此目的的一种方法。另一种方法是使用Handler和postDelayed方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | private boolean started = false; private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { final Random random = new Random(); int i = random.nextInt(2 - 0 + 1) + 0; random_note.setImageResource(image[i]); if(started) { start(); } } }; public void stop() { started = false; handler.removeCallbacks(runnable); } public void start() { started = true; handler.postDelayed(runnable, 2000); } |
这是一个使用Timer和TimerTask的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private Timer timer; private TimerTask timerTask = new TimerTask() { @Override public void run() { final Random random = new Random(); int i = random.nextInt(2 - 0 + 1) + 0; random_note.setImageResource(image[i]); } }; public void start() { if(timer != null) { return; } timer = new Timer(); timer.scheduleAtFixedRate(timerTask, 0, 2000); } public void stop() { timer.cancel(); timer = null; } |
您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | private CountDownTimer timer; timer = new CountDownTimer(5000, 20) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { try{ yourMethod(); }catch(Exception e){ Log.e("Error","Error:" + e.toString()); } } }.start(); |
然后再次调用计时器:
1 2 3 4 | public void yourMethod(){ //do what you want timer.start(); } |
要取消计时器,可以调用
希望能帮助到你!
您可以使用RxJava2 / RxAndroid2并创建一个Observable,它每秒发送一条消息(或您想要的任何消息),例如使用伪代码:
1 2 3 4 5 6 7 8 9 10 11 | Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS) .timeInterval() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Timed<Long>>() { @Override public void accept(@NonNull Timed<Long> longTimed) throws Exception { //your code here. Log.d(TAG, new DateTime()); } }); |
当您想要停止它时,您可以简单地调用:
1 | timer.dispose(); |
我发现此代码比其他选项更具可读性。
除了要提及使用Handler,CountDownTimer和常规Timer之间的区别之外,我没有其他要添加的内容。如britzl所述,CountDownTimer在内部使用处理程序,因此等效于直接使用处理程序。处理程序用于在短时间内运行Ui东西。一个例子是文本视图的setText。对于计算量大的任务,处理程序可能会导致延迟。计时器也只能运行简短的任务,但不一定只用于UI。对于更复杂的任务,应使用新的线程。