在尝试限制电池使用时,我不需要繁忙的循环,所以我不确定如何解决这个问题。
如果我有一个允许某人唱歌45秒的节目,那么他们会暂停20秒钟来喝一杯,然后重复播放一些歌曲。
我的计时器位于Problem getting timer to work after cancelling one iteration and starting another,但为了使其正常工作,当有人点击按钮时,它会启动第一次倒计时,但时间排队,标题显示,然后是时间完成它将显示休息,然后在20秒后它将显示一个新标题。
所以使用sendMessageDelayed
是一个问题,虽然它适用于第一部分。
理想情况下,我希望在倒计时时返回Runnable
返回某个控制器函数,然后使用if语句。
void Controller(int curCount) {
if(curCount % 2 == 0) {
// call thread that uses runnable with next song time limit and title
} else {
// call thread with 20 and "REST"
}
}
但是,这只有在
时才有效Thread t = new Thread(runnable);
... // Go to controller, which will count down
t.join();
阻止直到完成。我可以做t.wait(time * 1000);
而不是t.join()
,但这可能有点迟或早,因为计时器在保持时间方面不会很完美,所以我认为它不正确。
那么做这样的事情的最佳方法是什么,没有不必要的轮询或繁忙的循环。
for(SongModel m : songList) {
countdownTime(m.getSongTime(), m.getTitle);
countdownTime(10, "REST");
}
修改
我想我目前的计时器问题还不清楚。由于消息排队等待,它将更改为 Rest ,同时仍然倒计时第一首歌曲的剩余时间,因为Runnable
的完成速度比Handler
处理的速度快得多。所以,这种方法存在一个缺陷,导致我认为使用sendMessageDelayed
的设计不会像我希望的那样工作,但是,如果我只需要倒计时一次/按钮点击就可以了,但我的需求是只需点击一下按钮就可以实现这一切,它会启动整个过程,然后在我的问题结束时模拟for
循环。
答案 0 :(得分:1)
我会使用Timer
和一对TimerTasks
来执行此操作。
Timer scheduler = new Timer("Song Scheduler");
TimerTask restTask = new TimerTask() {
public void run() {
// call rest code
scheduler.schedule(songTask, 20*1000);
}
};
TimerTask songTask = new TimerTask() {
public void run() {
// call song code
scheduler.schedule(restTask, 45*1000);
}
};
重要的是,在最后一个计时器到期之前,我不会安排下一个计时器。如果您希望songTask持续当前歌曲的长度(如您的代码所示)或45秒(如散文所示),您可以动态调整时间。无论哪种方式,基础都是一样的。
答案 1 :(得分:1)
我们又来了:)
我写了这个,并在Eclipse中使用Eclair模拟器对其进行了测试,运行正常。一次点击从54到0,然后从20到0,然后从45到0等,直到另一次点击取消它。如果符合您的需求,请告诉我。用户界面当然是最低限度的:
<强> TimerTest.java 强>
package com.aleadam.timertest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TimerTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.btn);
button.setOnClickListener(new MyListener ());
}
private class MyListener implements OnClickListener {
private long mStartTime = 0L;
private boolean started = false;
private boolean singing = true;
private final Handler mHandler = new Handler();
private Runnable mUpdateTimeTask;
TextView label, timer;
public MyListener() {
super();
label = (TextView) findViewById (R.id.lbl);
timer = (TextView) findViewById (R.id.timer);
}
public void onClick(View v) {
if (!started) {
started = true;
((Button) v).setText(R.string.button_label_stop);
mUpdateTimeTask = new Runnable() {
public void run() {
long millis = SystemClock.elapsedRealtime() - mStartTime;
if (singing && millis >= 45000L) {
label.setText(R.string.text_label_rest);
mStartTime = SystemClock.uptimeMillis();
timer.setText("20");
singing = false;
} else if (!singing && millis >= 20000L) {
label.setText(R.string.text_label_sing);
mStartTime = SystemClock.uptimeMillis();
timer.setText("45");
singing = true;
} else {
if (singing)
timer.setText(Long.toString(45-millis/1000));
else
timer.setText(Long.toString(20-millis/1000));
}
mHandler.postDelayed (mUpdateTimeTask, 1000);
}
};
singing = true;
mStartTime = SystemClock.uptimeMillis();
label.setText(R.string.text_label_sing);
timer.setText("45");
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 1000);
} else {
started = false;
mHandler.removeCallbacks(mUpdateTimeTask);
label.setText("");
timer.setText("");
((Button) v).setText(R.string.button_label_start);
}
}
}
}
<强> main.xml中强>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title_label"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button_label_start"
android:id="@+id/btn"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/lbl"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/timer"
android:textSize="24dp"
android:textStyle="bold"
android:typeface="monospace"/>
</LinearLayout>
<强>的strings.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title_label">Timer test - 45 + 20 sec</string>
<string name="app_name">Timer Test</string>
<string name="button_label_start">Click to start</string>
<string name="text_label_sing">Sing for 45 seconds</string>
<string name="text_label_rest">20 seconds to drink!</string>
<string name="button_label_stop">Click to cancel</string>
</resources>