How to set a timer in android

前端 未结 13 1703
天命终不由人
天命终不由人 2020-11-22 06:43

What is the proper way to set a timer in android in order to kick off a task (a function that I create which does not change the UI)? Use this the Java way: http://docs.ora

相关标签:
13条回答
  • 2020-11-22 06:59

    Here we go.. We will need two classes. I am posting a code which changes mobile audio profile after each 5 seconds (5000 mili seconds) ...

    Our 1st Class

    public class ChangeProfileActivityMain extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
    
            Timer timer = new Timer();
            TimerTask updateProfile = new CustomTimerTask(ChangeProfileActivityMain.this);
            timer.scheduleAtFixedRate(updateProfile, 0, 5000);
        }
    
    }
    

    Our 2nd Class

    public class CustomTimerTask extends TimerTask {
    
        private AudioManager audioManager;
        private Context context;
        private Handler mHandler = new Handler();
    
        // Write Custom Constructor to pass Context
        public CustomTimerTask(Context con) {
            this.context = con;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
    
            // your code starts here.
            // I have used Thread and Handler as we can not show Toast without starting new thread when we are inside a thread.
            // As TimePicker has run() thread running., So We must show Toast through Handler.post in a new Thread. Thats how it works in Android..
            new Thread(new Runnable() {
                @Override
                public void run() {
                    audioManager = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
                                audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
                                Toast.makeText(context, "Ringer Mode set to Normal", Toast.LENGTH_SHORT).show();
                            } else {
                                audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
                                Toast.makeText(context, "Ringer Mode set to Silent", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }).start();
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 07:01

    I am using a handler and runnable to create a timer. I wrapper this in an abstract class. Just derive/implement it and you are good to go:

     public static abstract class SimpleTimer {
        abstract void onTimer();
    
        private Runnable runnableCode = null;
        private Handler handler = new Handler();
    
        void startDelayed(final int intervalMS, int delayMS) {
            runnableCode = new Runnable() {
                @Override
                public void run() {
                    handler.postDelayed(runnableCode, intervalMS);
                    onTimer();
                }
            };
            handler.postDelayed(runnableCode, delayMS);
        }
    
        void start(final int intervalMS) {
            startDelayed(intervalMS, 0);
        }
    
        void stop() {
            handler.removeCallbacks(runnableCode);
        }
    }
    

    Note that the handler.postDelayed is called before the code to be executed - this will make the timer more closed timed as "expected". However in cases were the timer runs to frequently and the task (onTimer()) is long - there might be overlaps. If you want to start counting intervalMS after the task is done, move the onTimer() call a line above.

    0 讨论(0)
  • 2020-11-22 07:04

    As I have seen it, java.util.Timer is the most used for implementing a timer.

    For a repeating task:

    new Timer().scheduleAtFixedRate(task, after, interval);
    

    For a single run of a task:

    new Timer().schedule(task, after);
    


    task being the method to be executed
    after the time to initial execution
    (interval the time for repeating the execution)

    0 讨论(0)
  • 2020-11-22 07:04

    this example start the timer unitl destroyed in Kotlin

    private lateinit var timerTask: TimerTask
    
     timerTask = object : TimerTask() {
            override fun run() {
                Log.d("KTZ", "$minutes:$seconds");
                timeRecordingLiveData.postValue("$minutes:$seconds")
                seconds += 1;
                if (seconds == 60) {
                    Log.d("KTZ", "$minutes:$seconds");
                    timeRecordingLiveData.postValue("$minutes:$seconds")
                    seconds = 0;
                    minutes += 1;
                }
            }
    
        }
    

    Cancel the timertask in onDestroy()

    timerTask.cancel()
    
    0 讨论(0)
  • 2020-11-22 07:08

    yes java's timer can be used, but as the question asks for better way (for mobile). Which is explained Here.


    For the sake of StackOverflow:

    Since Timer creates a new thread it may be considered heavy,

    if all you need is to get is a call back while the activity is running a Handler can be used in conjunction with a

    Runnable:

    private final int interval = 1000; // 1 Second
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable(){
        public void run() {
            Toast.makeText(MyActivity.this, "C'Mom no hands!", Toast.LENGTH_SHORT).show();
        }
    };
    ...
    handler.postAtTime(runnable, System.currentTimeMillis()+interval);
    handler.postDelayed(runnable, interval);
    

    or a Message

    private final int EVENT1 = 1; 
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {         
            case Event1:
                Toast.makeText(MyActivity.this, "Event 1", Toast.LENGTH_SHORT).show();
                break;
    
            default:
                Toast.makeText(MyActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
                break;
            }
        }
    };
    
    ...
    
    Message msg = handler.obtainMessage(EVENT1);
    handler.sendMessageAtTime(msg, System.currentTimeMillis()+interval);
    handler.sendMessageDelayed(msg, interval);
    

    on a side note this approach can be used, if you want to run a piece of code in the UI thread from an another thread.

    if you need to get a call back even if your activity is not running then, you can use an AlarmManager

    0 讨论(0)
  • 2020-11-22 07:09

    I'm an Android newbie but here is the timer class I created based on the answers above. It works for my app but I welcome any suggestions.

    Usage example:

    ...{
    public Handler uiHandler = new Handler();
    
      private Runnable runMethod = new Runnable()
        {
            public void run()
            {
                  // do something
            }
        };
    
        timer = new UITimer(handler, runMethod, timeoutSeconds*1000);       
            timer.start();
    }...
    
    public class UITimer
    {
        private Handler handler;
        private Runnable runMethod;
        private int intervalMs;
        private boolean enabled = false;
        private boolean oneTime = false;
    
        public UITimer(Handler handler, Runnable runMethod, int intervalMs)
        {
            this.handler = handler;
            this.runMethod = runMethod;
            this.intervalMs = intervalMs;
        }
    
        public UITimer(Handler handler, Runnable runMethod, int intervalMs, boolean oneTime)
        {
            this(handler, runMethod, intervalMs);
            this.oneTime = oneTime;
        }
    
        public void start()
        {
            if (enabled)
                return;
    
            if (intervalMs < 1)
            {
                Log.e("timer start", "Invalid interval:" + intervalMs);
                return;
            }
    
            enabled = true;
            handler.postDelayed(timer_tick, intervalMs);        
        }
    
        public void stop()
        {
            if (!enabled)
                return;
    
            enabled = false;
            handler.removeCallbacks(runMethod);
            handler.removeCallbacks(timer_tick);
        }
    
        public boolean isEnabled()
        {
            return enabled;
        }
    
        private Runnable timer_tick = new Runnable()
        {
            public void run()
            {
                if (!enabled)
                    return;
    
                handler.post(runMethod);
    
                if (oneTime)
                {
                    enabled = false;
                    return;
                }
    
                handler.postDelayed(timer_tick, intervalMs);
            }
        }; 
    }
    
    0 讨论(0)
提交回复
热议问题