Android - 希望应用程序每秒执行一次任务

时间:2012-02-23 02:59:44

标签: android timer action handler

我正在尝试让我的倒计时应用程序执行其更新当前时间和日期TextView的功能,并每秒触发其MyOnItemSelectedListener,以便应用程序动态倒计时,而不是仅在启动onCreate时。如果有一个更有效的方法然后快速解雇MyOnItemSelectedListener我会很感激批评。

public class TheCount extends Activity {
TextView description=null;
TextView dates=null;
TextView times=null;
TextView output=null;
TextView cDateDisplay=null;
TextView cTimeDisplay=null;
private int mYear;
private int mMonth;
private int mDay;
private int mHour;
private int mMinute;
private int mSecond;
CountdownHelper helper=null;
String countdownId=null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.thecount);
    helper=new CountdownHelper(this);
    cTimeDisplay = (TextView)findViewById(R.id.lblCurTime);
    cDateDisplay = (TextView)findViewById(R.id.lblCurDate);

    final Calendar c = Calendar.getInstance();
    mYear = c.get(Calendar.YEAR);
    mMonth = c.get(Calendar.MONTH);
    mDay = c.get(Calendar.DAY_OF_MONTH);
    mHour = c.get(Calendar.HOUR_OF_DAY);
    mMinute = c.get(Calendar.MINUTE);
    mSecond = c.get(Calendar.SECOND);

    Spinner spinner = (Spinner) findViewById(R.id.spinner1);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            this, R.array.countoptions, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    description =(TextView)findViewById(R.id.lblDescriptFed);
    dates =(TextView)findViewById(R.id.lblDateFed);
    times =(TextView)findViewById(R.id.lblTimeFed);
    output =(TextView)findViewById(R.id.lblOutput);

    countdownId=getIntent().getStringExtra(MainActivity.ID_EXTRA);
    if (countdownId!=null) {
        load();
    }

    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());

    updateDisplay();

}

private void updateDisplay() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
//@Override
public void run() {
    updatedDisplay();
    }
},0,1000);//Update text every second

}

public class MyOnItemSelectedListener implements OnItemSelectedListener {
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {

        if (parent.getItemAtPosition(pos).toString().equals("Normal")){
            Toast.makeText(parent.getContext(), "Countdown format is " +
                  parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
            convertTime();
        } else if (parent.getItemAtPosition(pos).toString().equals("by Days")){
            Toast.makeText(parent.getContext(), "Countdown format " +
                      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
                convertDays();
        } else if (parent.getItemAtPosition(pos).toString().equals("by Hours")){
            Toast.makeText(parent.getContext(), "Countdown format " +
                      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
                convertHours();
        } else if (parent.getItemAtPosition(pos).toString().equals("by Minutes")){
            Toast.makeText(parent.getContext(), "Countdown format " +
                      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
                convertMinutes();
        } else if (parent.getItemAtPosition(pos).toString().equals("by Seconds")){
            Toast.makeText(parent.getContext(), "Countdown format " +
                      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
                convertSeconds();
        }

    }
    public void onNothingSelected(AdapterView parent) {
      // Do nothing.
    }
}

private void convertTime() {
    String dtCountdown = dates.getText().toString() + " " + times.getText().toString();
    String dtCurrent = cDateDisplay.getText().toString() + " " + cTimeDisplay.getText().toString();
    SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");  
    try {  
        Date date = format.parse(dtCountdown);
        Date dateCur = format.parse(dtCurrent);
        long diff = dateCur.getTime() - date.getTime();

        int timeInSeconds = (int) (diff / 1000);
        int days, hours, minutes, seconds;
        days = timeInSeconds / 86400;
        timeInSeconds = timeInSeconds - (days * 86400);
        hours = timeInSeconds / 3600;
        timeInSeconds = timeInSeconds - (hours * 3600);
        minutes = timeInSeconds / 60;
        timeInSeconds = timeInSeconds - (minutes * 60);
        seconds = timeInSeconds;


        System.out.println(date); 
        if(dateCur.compareTo(date)>0){
            output.setText(String.valueOf(days) + " days " + String.valueOf(hours) +
                    " hours \n" + String.valueOf(minutes) + " minutes " + String.valueOf(seconds) + " seconds ago");
        } else {
            output.setText(String.valueOf(Math.abs(days)) + " days " + String.valueOf(Math.abs(hours)) +
                    " hours \n" + String.valueOf(Math.abs(minutes)) + " minutes " + String.valueOf(Math.abs(seconds)) + " seconds till");
        }

    } catch (ParseException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
}

private void convertDays() {
    String dtCountdown = dates.getText().toString() + " " + times.getText().toString();
    String dtCurrent = cDateDisplay.getText().toString() + " " + cTimeDisplay.getText().toString();
    SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy hh:mm");  
    try {  
        Date date = format.parse(dtCountdown);
        Date dateCur = format.parse(dtCurrent);
        long diff = dateCur.getTime() - date.getTime();

        int timeInSeconds = (int) (diff / 1000);
        int days;
        days = timeInSeconds / 86400;

        System.out.println(date); 
        if(dateCur.compareTo(date)>0){
            output.setText(String.valueOf(days) + " days ago");
        } else {
            output.setText(String.valueOf(Math.abs(days)) + " days till");
        }

    } catch (ParseException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
}

private void convertHours() {
    String dtCountdown = dates.getText().toString() + " " + times.getText().toString();
    String dtCurrent = cDateDisplay.getText().toString() + " " + cTimeDisplay.getText().toString();
    SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy hh:mm");  
    try {  
        Date date = format.parse(dtCountdown);
        Date dateCur = format.parse(dtCurrent);
        long diff = dateCur.getTime() - date.getTime();

        int timeInSeconds = (int) (diff / 1000);
        int hours;

        hours = timeInSeconds / 3600;

        System.out.println(date); 
        if(dateCur.compareTo(date)>0){
            output.setText(String.valueOf(hours) + " hours ago");
        } else {
            output.setText(String.valueOf(Math.abs(hours)) + " hours till");
        }

    } catch (ParseException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
}

private void convertMinutes() {
    String dtCountdown = dates.getText().toString() + " " + times.getText().toString();
    String dtCurrent = cDateDisplay.getText().toString() + " " + cTimeDisplay.getText().toString();
    SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy hh:mm");  
    try {  
        Date date = format.parse(dtCountdown);
        Date dateCur = format.parse(dtCurrent);
        long diff = dateCur.getTime() - date.getTime();

        int timeInSeconds = (int) (diff / 1000);
        int minutes;

        minutes = timeInSeconds / 60;

        System.out.println(date); 
        if(dateCur.compareTo(date)>0){
            output.setText(String.valueOf(minutes) + " minutes ago");
        } else {
            output.setText(String.valueOf(Math.abs(minutes)) + " minutes till");
        }

    } catch (ParseException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
}

private void convertSeconds() {
    String dtCountdown = dates.getText().toString() + " " + times.getText().toString();
    String dtCurrent = cDateDisplay.getText().toString() + " " + cTimeDisplay.getText().toString();
    SimpleDateFormat  format = new SimpleDateFormat("dd/MM/yyyy hh:mm");  
    try {  
        Date date = format.parse(dtCountdown);
        Date dateCur = format.parse(dtCurrent);
        long diff = dateCur.getTime() - date.getTime();

        int timeInSeconds = (int) (diff / 1000);
        int seconds;
        seconds = timeInSeconds;

        System.out.println(date); 
        if(dateCur.compareTo(date)>0){
            output.setText(String.valueOf(seconds) + " seconds ago");
        } else {
            output.setText(String.valueOf(Math.abs(seconds)) + " seconds till");
        }

    } catch (ParseException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }
}

private void updatedDisplay() {
    TextView cDateDisplay=null;
    TextView cTimeDisplay=null;
    cTimeDisplay = (TextView)findViewById(R.id.lblCurTime);
    cDateDisplay = (TextView)findViewById(R.id.lblCurDate);
    cDateDisplay.setText(
        new StringBuilder()
                // Month is 0 based so add 1
                .append(mDay).append("/")
                .append(mMonth + 1).append("/")
                .append(mYear).append(" "));
    cTimeDisplay.setText(
            new StringBuilder()
                    .append(pad(mHour)).append(":")
                    .append(pad(mMinute)).append(":").append(pad(mSecond)));
}

private static String pad(int c) {
    if (c >= 10)
        return String.valueOf(c);
    else
        return "0" + String.valueOf(c);
}  

private void load() {
    Cursor c=helper.getById(countdownId);

    c.moveToFirst();    
    description.setText(helper.getDescription(c));
    dates.setText(helper.getDate(c));
    times.setText(helper.getTime(c) + ":00");

    c.close();
}

@Override
public void onDestroy() {
    super.onDestroy();

    helper.close();
}

}

@NamLe:这会导致应用程序崩溃,并在调用onCreate()时将其提交到LogCat中。

02-23 13:19:43.540: I/System.out(11667): Sun Jun 24 00:00:00 MDT 2012 02-23 13:19:44.500: W/dalvikvm(11667): threadid=11: thread exiting with uncaught exception (group=0x40a351f8) 02-23 13:19:44.510: E/AndroidRuntime(11667): FATAL EXCEPTION: Timer-0 02-23 13:19:44.510: E/AndroidRuntime(11667): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:709) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.View.requestLayout(View.java:12675) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.View.requestLayout(View.java:12675) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.View.requestLayout(View.java:12675) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.View.requestLayout(View.java:12675) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.view.View.requestLayout(View.java:12675) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.widget.TextView.checkForRelayout(TextView.java:6773) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.widget.TextView.setText(TextView.java:3306) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.widget.TextView.setText(TextView.java:3162) 02-23 13:19:44.510: E/AndroidRuntime(11667): at android.widget.TextView.setText(TextView.java:3137) 02-23 13:19:44.510: E/AndroidRuntime(11667): at com.pixelcrunch.crunchtime.TheCount$1.run(TheCount.java:87) 02-23 13:19:44.510: E/AndroidRuntime(11667): at java.util.Timer$TimerImpl.run(Timer.java:284)

4 个答案:

答案 0 :(得分:22)

尝试使用UpdateDisplay功能,如下所示:

private void updateDisplay() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {

        @Override
        public void run() {
            Calendar c = Calendar.getInstance();
            mYear = c.get(Calendar.YEAR);
            mMonth = c.get(Calendar.MONTH);
            mDay = c.get(Calendar.DAY_OF_MONTH);
            mHour = c.get(Calendar.HOUR_OF_DAY);
            mMinute = c.get(Calendar.MINUTE);
            mSecond = c.get(Calendar.SECOND);

            cDateDisplay.setText(new StringBuilder()
                // Month is 0 based so add 1
                .append(mDay).append("/")
                .append(mMonth + 1).append("/")
                .append(mYear).append(" "));

            cTimeDisplay.setText(
                new StringBuilder()
                    .append(pad(mHour)).append(":")
                    .append(pad(mMinute)).append(":").append(pad(mSecond))
            );
        }

    },0,1000);//Update text every second
}

最后,您必须在updateDisplay()函数中调用onCreate()
我希望这段代码可以帮助你完成你想要的东西!

答案 1 :(得分:1)

在主线程上运行它:

        new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    yourMethodOnTheMainThread();
                }
            });
        }
    },0,10000);

答案 2 :(得分:0)

您可以使用sendMessageAtTime()postAtTime()在将来发送一条消息,然后再处理。

For more information.

答案 3 :(得分:0)

也许您也可以使用Timer / TimerTask重复触发操作:https://developer.android.com/reference/java/util/Timer.html