如何在android中设置一个计时器
什么是正确的方法来设置一个计时器在Android中启动一个任务(我创build一个不改变用户界面的function)? 使用这种Java方式: http : //docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
或者有一个更好的方式在android(android的处理程序)?
通过java.util.Timer和java.util.TimerTask使用定时器的标准Java方法在Android 中可以正常工作,但是您应该知道这种方法会创build一个新的线程。
您可以考虑使用非常方便的Handler类(android.os.Handler),并通过sendMessageAtTime(android.os.Message, long)
或sendMessageDelayed(android.os.Message, long)
将消息发送到处理程序。 一旦收到消息,您可以运行所需的任务。 第二个选项是创build一个Runnable对象,并通过Handler的函数postAtTime(java.lang.Runnable, long)
或postDelayed(java.lang.Runnable, long)
调度它。
是java的定时器可以使用 ,但作为问题要求更好的方式 (手机)。 这里解释一下 。
为了StackOverflow:
由于Timer创build一个新的线程可能会被认为是沉重的,
如果你所需要的只是在活动运行时得到一个callback, Handler可以和a一起使用
可运行 :
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);
或消息
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);
在旁边注意这个方法可以使用,如果你想在另一个线程的UI线程中运行一段代码。
如果您需要回电话,即使您的活动没有运行,您也可以使用AlarmManager
正如我所看到的, java.util.Timer是最常用于实现一个计时器。
对于重复的任务:
new Timer().scheduleAtFixedRate(task, after, interval);
对于任务的单个运行:
new Timer().schedule(task, after);
任务是要执行的方法
在最初的执行时间之后
( 间隔重复执行的时间)
这是情景。
Android文档build议你应该使用AlarmManager来注册一个Intent,如果你的应用程序可能没有运行,它将在指定的时间触发。
否则,你应该使用Handler。
注意:“报警pipe理器”适用于希望在特定时间运行应用程序代码的情况,即使您的应用程序当前未在运行。 对于正常的定时操作(滴答,超时等),使用Handler更容易,效率更高。
可能是Timerconcept
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval public void onTick(long millisUntilFinished) { } public void onFinish() { } }.start();
要么
方法2 ::
编程计时器
添加一个名为time的intvariables。 将其设置为0.将以下代码添加到MainActivity.java中的onCreate函数。
//Declare the timer Timer t = new Timer(); //Set the schedule function and rate t.scheduleAtFixedRate(new TimerTask() { @Override public void run() { //Called each time when 1000 milliseconds (1 second) (the period parameter) } }, //Set how long before to start calling the TimerTask (in milliseconds) 0, //Set the amount of time between each execution (in milliseconds) 1000);
进入运行方法并添加下面的代码。
//We must use this function in order to change the text view text runOnUiThread(new Runnable() { @Override public void run() { TextView tv = (TextView) findViewById(R.id.main_timer_text); tv.setText(String.valueOf(time)); time += 1; } });
这里我们去..我们将需要两个类。 我发布一个代码,每5秒(5000毫秒)后更改移动audioconfiguration文件…
我们的第一类
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); } }
我们的第二类
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(); } }
我希望这一个是有益的,可能会花费较less的努力来实现Android CountDownTimer类
例如
new CountDownTimer(30000, 1000) { public void onTick(long millisUntilFinished) { mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); } public void onFinish() { mTextField.setText("done!"); } }.start();
我是一个Android新手,但这里是我根据上面的答案创build的计时器类。 它适用于我的应用程序,但我欢迎任何build议。
用法示例:
...{ 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); } }; }
我相信在android上这样做是因为你需要一个后台服务来运行。 在该后台应用程序中,创build计时器。 当计时器“滴答”(设置你想要等待的时间间隔),启动你想要开始的活动。
http://developer.android.com/guide/topics/fundamentals.html (< – 这篇文章解释了Android开发的活动,服务,意图和其他核心基础之间的关系)
对于定时操作,你应该使用Handler。 请参阅http://developer.android.com/resources/articles/timed-ui-updates.html
如果您需要运行后台服务,则需要使用AlarmManager。 看看BuzzBox SDK
http://hub.buzzbox.com/android-sdk/
您可以创build一个任务,并使用cronstring进行排定,它将与linux上的crontab类似
我曾经使用( Timer
, TimerTask
)和Handler
来周期性地启动(耗时)任务。 现在我把整个切换到RxJava。 RxJava提供的Observable.timer
更简单,更容易出错,使用起来也很轻松。
public class BetterTimerFragment extends Fragment { public static final String TAG = "BetterTimer"; private TextView timeView; private Subscription timerSubscription; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_timer, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); timeView = (TextView) view.findViewById(R.id.timeView); } @Override public void onResume() { super.onResume(); // Right after the app is visible to users, delay 2 seconds // then kick off a (heavy) task every 10 seconds. timerSubscription = Observable.timer(2, 10, TimeUnit.SECONDS) .map(new Func1<Long, String>() { @Override public String call(Long unused) { // TODO: Probably do time-consuming work here. // This runs on a different thread than the main thread. return "Time: " + System.currentTimeMillis(); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String timeText) { // The result will then be propagated back to the main thread. timeView.setText(timeText); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { Log.e(TAG, throwable.getMessage(), throwable); } }); } @Override public void onPause() { super.onPause(); // Don't kick off tasks when the app gets invisible. timerSubscription.unsubscribe(); } }
我正在使用一个处理程序和可运行来创build一个计时器。 我把这个包装在一个抽象类中。 只是推导/实施它,你很好去:
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); } }
请注意, handler.postDelayed
在要执行的代码之前被调用 – 这将使计时器的closures时间定为“预期”。 然而,在计时器频繁运行的情况下,任务( onTimer()
)很长 – 可能会有重叠。 如果要在任务完成后开始计数intervalMS
,请将onTimer()
调用上面的一行。