如何在机器人中设置计时器

在 android 中设置计时器以启动任务(我创建的一个函数不会改变 UI)的正确方法是什么? 使用 Java 的方式: Http://docs.oracle.com/javase/1.5.0/docs/api/java/util/timer.html

或者在 android (android 的处理程序)中有更好的方法?

470865 次浏览

我相信在机器人上做到这一点的方法是你需要一个后台服务来运行。在该后台应用程序中,创建计时器。当计时器“滴答”(设置您想要等待的时间间隔)时,启动您想要启动的活动。

Http://developer.Android.com/guide/topics/fundamentals.html (本文解释了活动、服务、意图和 Android 开发的其他核心基本原理之间的关系)

通过 Java.util 定时器定时器任务使用计时器的标准 Java 方法在 Android 中可以很好地工作,但是您应该注意,这种方法创建了一个新线程。

您可以考虑使用非常方便的 管理员类(android.os。处理程序) ,并通过 sendMessageAtTime(android.os.Message, long)sendMessageDelayed(android.os.Message, long)向处理程序发送消息。一旦收到消息,就可以运行所需的任务。第二个选择是创建一个 可以跑对象,并通过 Handler 的函数 postAtTime(java.lang.Runnable, long)postDelayed(java.lang.Runnable, long)对其进行调度。

正如我所看到的,Java.util 定时器是最常用于实现计时器的。

对于重复的任务:

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

对于任务的单次运行:

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


Task 作为要执行的方法
初始执行时间之后
(间隔重复执行的时间) < br/>

这是情境性的。

Android 文档建议您应该使用 警报管理器注册一个意图,如果您的应用程序可能无法运行,该意图将在指定时间触发。

否则,应该使用 Handler。

注意: 警报管理器的目的是 如果你想让你的 应用程序代码运行在特定的 时间,即使你的申请 正在运行。正常时间 操作(刻度、超时等) 更容易,也更有效率 使用处理程序。

是的,java 的定时器 可以使用,但是当问题要求 更好的方式(移动)。这是解释 这里


为了 StackOverflow:

因为 定时器创建了一个新的线程,所以它可能被认为很重,

如果您需要的只是在活动运行时获取回调,则可以将 < strong > Handler

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);

或者 译自: 美国《科学》杂志网站(http://developer.android.com/reference/android/os/Message.html)原文地址: http://developer.android.com/reference/android/os/Message.html

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 线程中的一段代码,可以使用这种方法。

警告: 每当 CPU 进入深度睡眠时,Handler的计时器(或任何控制延迟的东西)就会暂停,但是一旦 CPU 醒来(从暂停的地方) ,它就会继续。

如果您需要得到一个回电,即使您的活动没有运行然后,您可以使用 < strong > AlarmManager

对于计时操作,您应该使用 管理员

如果你需要运行一个后台服务,AlarmManager 是一个不错的选择。

我是一个 Android 新手,但是这里是我根据上面的答案创建的计时器类。它适用于我的应用程序,但我欢迎任何建议。

用法例子:

...{
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);
}
};
}

开始了。.我们需要两节课。我张贴的代码,改变移动音频配置文件后每5秒(5000毫秒) ..。

我们的一班

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();


}


}

可能是 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();

或者

方法二:

设定计时器

添加一个名为 time 的 int 变量,将其设置为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);

进入 run 方法并添加以下代码。

//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;
}


});

我希望这个方法能够有所帮助,并且可以少花些力气去实现, Android CountDownTimer 类

例如:。

 new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}


public void onFinish() {
mTextField.setText("done!");
}
}.start();

我过去常常使用(TimerTimerTask)和 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();
}
}

我正在使用一个处理程序和运行,以创建一个计时器。我将其包装在一个抽象类中。只要推导/实现它,你就可以开始了:

 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-这将使计时器按照“预期”更加关闭。但是,如果计时器运行频繁,任务(onTimer())很长,则可能存在重叠。如果您想在任务完成后开始计数 intervalMS,请将 onTimer()调用移动到上面一行。

这个例子启动计时器直到在 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;
}
}


}

取消 onDestroy ()中的 timer 任务

timerTask.cancel()