计数45秒,停顿20然后重复使用不同的标题 [英] Count for 45 seconds, pause for 20 then repeat with different title

查看:118
本文介绍了计数45秒,停顿20然后重复使用不同的标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

如果我有一个计划,让别人唱45秒,然后他们暂停20秒,喝一杯,然后重复,对于歌曲的一些数字。

我的计时器是在<一个href="http://stackoverflow.com/questions/5751570/problem-getting-timer-to-work-after-cancelling-one-iteration-and-starting-another/5774610#5774610">Problem越来越定时器取消一个迭代,并开始另一个后继续工作,但为了这个工作,当有人点击一个按钮,启动了第一个倒计时,但时间进行排队,并在标题中显示,然后当时间完成,它会显示的恢复的,然后20秒后,它会显示一个新的标题。

所以,使用 sendMessageDelayed 是一个问题,但它为第一部分。

我非常希望能有的Runnable 返回当倒数至零时,某些控制器功能,然后将使用if语句。

 无效控制器(INT curCount){
  如果(curCount%2 == 0){
     使用可运行与下一首歌曲的时间限制和标题//调用线程
  } 其他 {
     //调用线程与20和休息
  }
}
 

但是,这只会当

工作

 线程t =新主题(可运行);
... //去控制,这会倒计时
t.join();
 

阻塞,直到完成。我可以做 t.wait(时间* 1000); 而不是 t.join(),但可能是有点迟或早,定时器不会是完美的,在保存时间,所以我不认为这是正确的。

那么,什么是做这样的事情最好的办法,没有不必要的轮询或忙循环。

 的(SongModel M:的SongList){
  countdownTime(m.getSongTime(),m.getTitle);
  countdownTime(10,休息);
}
 

编辑:

我想我是不清楚我目前的计时器问题。由于消息被排队它将改变到的恢复的同时仍然倒计时留下的第一首歌时,因为的Runnable 完成更迅速比处理程序正在处理。因此,有在这种方法中的一个缺陷,导致我使用 sendMessageDelayed 将无法工作,因为我曾希望想对于这样的设计,不过,如果我只需要算下一次/按钮,点击它会被罚款,但我需要的是有这一切都发生在点击一个按钮,它会启动进程,然后应该模拟回路中我的问题到底。

解决方案

在这里,我们再次:)

我写了这一点,并与Eclair的模拟器测试它在Eclipse中,并运行良好。点击计数从54到0,然后从20至0,则45至0,等等,直到另一点击取消它。让我知道,如果它是由您的需求。当然,用户界面​​只是最低限度:

TimerTest.java

 包com.aleadam.timertest;

进口android.app.Activity;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.SystemClock;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.widget.Button;
进口android.widget.TextView;

公共类TimerTest延伸活动{
    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

        Button按钮=(按钮)findViewById(R.id.btn);
        button.setOnClickListener(新myListener的());
    }

    私有类myListener的实现OnClickListener {
        专用长mStartTime = 0L;
        私人布尔开始= FALSE;
        私人布尔歌唱= TRUE;
        私人最终处理程序mHandler =新的处理程序();
        私人的Runnable mUpdateTimeTask;
        TextView的标签,定时器;

        公共myListener的(){
            超();
            标签=(TextView中)findViewById(R.id.lbl);
            计时器=(TextView中)findViewById(R.id.timer);
        }
        公共无效的onClick(视图v){
            如果(!开始){
                开始= TRUE;
                ((按钮)V).setText(R.string.button_label_stop);
                mUpdateTimeTask =新的Runnable(){
                    公共无效的run(){
                        长米利斯= SystemClock.elapsedRealtime() -  mStartTime;
                        如果(唱歌和放大器;&安培;米利斯&GT; = 45000L){
                            label.setText(R.string.text_label_rest);
                            mStartTime = SystemClock.uptimeMillis();
                            timer.setText(20);
                            演唱= FALSE;
                        }否则如果(唱歌和放大器;!&安培;米利斯&GT; = 20000L){
                            label.setText(R.string.text_label_sing);
                            mStartTime = SystemClock.uptimeMillis();
                            timer.setText(45);
                            演唱= TRUE;
                        } 其他 {
                            如果(唱)
                                timer.setText(Long.toString(45米利斯/ 1000));
                            其他
                                timer.setText(Long.toString(20米利斯/ 1000));
                        }
                        mHandler.postDelayed(mUpdateTimeTask,1000);
                    }
                };
                演唱= TRUE;
                mStartTime = SystemClock.uptimeMillis();
                label.setText(R.string.text_label_sing);
                timer.setText(45);
                mHandler.removeCallbacks(mUpdateTimeTask);
                mHandler.postDelayed(mUpdateTimeTask,1000);
            } 其他 {
                开始= FALSE;
                mHandler.removeCallbacks(mUpdateTimeTask);
                label.setText();
                timer.setText();
                ((按钮)V).setText(R.string.button_label_start);
            }
        }
    }
}
 

的main.xml

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT; LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    &GT;
&LT;的TextView
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=@字符串/ title_label
    /&GT;
&LT;按钮
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=@字符串/ button_label_start
    机器人:ID =@ + ID / BTN。
    /&GT;
&LT;的TextView
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:ID =@ + ID / LBL
    /&GT;
&LT;的TextView
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    机器人:ID =@ + ID /定时器
    机器人:TEXTSIZE =24dp
    机器人:TEXTSTYLE =黑体
    机器人:字体=等宽/&GT;
&LT; / LinearLayout中&GT;
 

的strings.xml

 &LT; XML版本=1.0编码=UTF-8&GT?;
&LT;资源&GT;
    &LT;字符串名称=title_label&GT;计时器测试 -  45 + 20秒&LT; /串&GT;
    &LT;字符串名称=APP_NAME&GT;定时器测试和LT; /串&GT;
    &LT;字符串名称=button_label_start&gt;点击开始&LT; /串&GT;
    &LT;字符串名称=text_label_sing&GT;唱45秒-1 /串&GT;
    &LT;字符串名称=text_label_rest&GT;!20秒,喝&LT; /串&GT;
    &LT;字符串名称=button_label_stop&gt;点击取消&LT; /串&GT;
&LT; /资源&GT;
 

In trying to limit battery usage I need to not have busy loops, so I am not certain how to solve this problem.

If I have a program that will allow someone to sing for 45 seconds, then they pause for 20 seconds to get a drink, then repeat, for some number of songs.

My timer is at Problem getting timer to work after cancelling one iteration and starting another, but in order for this to work, when someone clicks on a button it starts the first countdown, but the times were queued up, and the title were displayed, then when the time is done it will show Rest, then after 20 seconds it will show a new title.

So use sendMessageDelayed is a problem, though it works for the first part.

Ideally I would like to have the Runnable return when the countdown is reached, to some controller function that would then use an if statement.

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"
  }
}

But, this would only work if

Thread t = new Thread(runnable);
... // Go to controller, which will count down
t.join();

blocked until done. I could do t.wait(time * 1000); instead of t.join(), but that may be a bit late or early as the timer won't be perfect at keeping time, so I don't think it is correct.

So what is the best way to do something like this, without needless polling or busy loops.

for(SongModel m : songList) {
  countdownTime(m.getSongTime(), m.getTitle);
  countdownTime(10, "REST");
}

Edit:

I think I was unclear about the problem with my current timer. Since the messages are queued up it will change to Rest while still counting down the time left for the first song, since the Runnable finishes much more quickly than the Handler is processing. So, there is a flaw in this approach that leads me to think for this design using a sendMessageDelayed won't work as I had hoped, though, if I just need to count down once/button click it will be fine, but my needs are to have this all happen with one button click, it starts the process, and then should simulate the for loop at the end of my question.

解决方案

Here we are again :)

I wrote this and tested it in Eclipse with an Eclair emulator, and running fine. One click counts from 54 to 0, then from 20 to 0, then 45 to 0, etc., until another click cancels it. Let me know if it's up to your needs. Of course the UI is just the bare minimum:

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>

这篇关于计数45秒,停顿20然后重复使用不同的标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆