How to set timer in android?

后端 未结 21 813
渐次进展
渐次进展 2020-11-22 00:51

Can someone give a simple example of updating a textfield every second or so?

I want to make a flying ball and need to calculate/update the ball coordinates every se

相关标签:
21条回答
  • 2020-11-22 01:46

    ok since this isn't cleared up yet there are 3 simple ways to handle this. Below is an example showing all 3 and at the bottom is an example showing just the method I believe is preferable. Also remember to clean up your tasks in onPause, saving state if necessary.

    
    import java.util.Timer;
    import java.util.TimerTask;
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.os.Handler.Callback;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class main extends Activity {
        TextView text, text2, text3;
        long starttime = 0;
        //this  posts a message to the main thread from our timertask
        //and updates the textfield
       final Handler h = new Handler(new Callback() {
    
            @Override
            public boolean handleMessage(Message msg) {
               long millis = System.currentTimeMillis() - starttime;
               int seconds = (int) (millis / 1000);
               int minutes = seconds / 60;
               seconds     = seconds % 60;
    
               text.setText(String.format("%d:%02d", minutes, seconds));
                return false;
            }
        });
       //runs without timer be reposting self
       Handler h2 = new Handler();
       Runnable run = new Runnable() {
    
            @Override
            public void run() {
               long millis = System.currentTimeMillis() - starttime;
               int seconds = (int) (millis / 1000);
               int minutes = seconds / 60;
               seconds     = seconds % 60;
    
               text3.setText(String.format("%d:%02d", minutes, seconds));
    
               h2.postDelayed(this, 500);
            }
        };
    
       //tells handler to send a message
       class firstTask extends TimerTask {
    
            @Override
            public void run() {
                h.sendEmptyMessage(0);
            }
       };
    
       //tells activity to run on ui thread
       class secondTask extends TimerTask {
    
            @Override
            public void run() {
                main.this.runOnUiThread(new Runnable() {
    
                    @Override
                    public void run() {
                       long millis = System.currentTimeMillis() - starttime;
                       int seconds = (int) (millis / 1000);
                       int minutes = seconds / 60;
                       seconds     = seconds % 60;
    
                       text2.setText(String.format("%d:%02d", minutes, seconds));
                    }
                });
            }
       };
    
    
       Timer timer = new Timer();
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            text = (TextView)findViewById(R.id.text);
            text2 = (TextView)findViewById(R.id.text2);
            text3 = (TextView)findViewById(R.id.text3);
    
            Button b = (Button)findViewById(R.id.button);
            b.setText("start");
            b.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Button b = (Button)v;
                    if(b.getText().equals("stop")){
                        timer.cancel();
                        timer.purge();
                        h2.removeCallbacks(run);
                        b.setText("start");
                    }else{
                        starttime = System.currentTimeMillis();
                        timer = new Timer();
                        timer.schedule(new firstTask(), 0,500);
                        timer.schedule(new secondTask(),  0,500);
                        h2.postDelayed(run, 0);
                        b.setText("stop");
                    }
                }
            });
        }
    
        @Override
        public void onPause() {
            super.onPause();
            timer.cancel();
            timer.purge();
            h2.removeCallbacks(run);
            Button b = (Button)findViewById(R.id.button);
            b.setText("start");
        }
    }
    
    
    

    the main thing to remember is that the UI can only be modified from the main ui thread so use a handler or activity.runOnUIThread(Runnable r);

    Here is what I consider to be the preferred method.

    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class TestActivity extends Activity {
    
        TextView timerTextView;
        long startTime = 0;
    
        //runs without a timer by reposting this handler at the end of the runnable
        Handler timerHandler = new Handler();
        Runnable timerRunnable = new Runnable() {
    
            @Override
            public void run() {
                long millis = System.currentTimeMillis() - startTime;
                int seconds = (int) (millis / 1000);
                int minutes = seconds / 60;
                seconds = seconds % 60;
    
                timerTextView.setText(String.format("%d:%02d", minutes, seconds));
    
                timerHandler.postDelayed(this, 500);
            }
        };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test_activity);
    
            timerTextView = (TextView) findViewById(R.id.timerTextView);
    
            Button b = (Button) findViewById(R.id.button);
            b.setText("start");
            b.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Button b = (Button) v;
                    if (b.getText().equals("stop")) {
                        timerHandler.removeCallbacks(timerRunnable);
                        b.setText("start");
                    } else {
                        startTime = System.currentTimeMillis();
                        timerHandler.postDelayed(timerRunnable, 0);
                        b.setText("stop");
                    }
                }
            });
        }
    
      @Override
        public void onPause() {
            super.onPause();
            timerHandler.removeCallbacks(timerRunnable);
            Button b = (Button)findViewById(R.id.button);
            b.setText("start");
        }
    
    }
    
    
    
    0 讨论(0)
  • 2020-11-22 01:46

    I think you can do it in Rx way like:

     timerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                          //TODO do your stuff
                    }
                });
    

    And cancel this like:

    timerSubscribe.unsubscribe();
    

    Rx Timer http://reactivex.io/documentation/operators/timer.html

    0 讨论(0)
  • 2020-11-22 01:47

    Because this question is still attracting a lot of users from google search(about Android timer) I would like to insert my two coins.

    First of all, the Timer class will be deprecated in Java 9 (read the accepted answer).

    The official suggested way is to use ScheduledThreadPoolExecutor which is more effective and features-rich that can additionally schedule commands to run after a given delay, or to execute periodically. Plus,it gives additional flexibility and capabilities of ThreadPoolExecutor.

    Here is an example of using plain functionalities.

    1. Create executor service:

      final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
      
    2. Just schedule you runnable:

      final Future<?> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
      
    3. You can now use future to cancel the task or check if it is done for example:

      future.isDone();
      

    Hope you will find this useful for creating a tasks in Android.

    Complete example:

    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    Future<?> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
    if (sampleFutureTimer.isDone()){
        // Do something which will save world.
    }
    
    0 讨论(0)
提交回复
热议问题