计数45秒,暂停20,然后重复不同的标题

时间:2011-04-26 00:26:25

标签: android timer

在尝试限制电池使用时,我不需要繁忙的循环,所以我不确定如何解决这个问题。

如果我有一个允许某人唱歌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循环。

2 个答案:

答案 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>