2012-02-23 17 views
6

Staram się, aby moja aplikacja do odliczania działała w celu aktualizacji mojej aktualnej godziny i daty TextView i odpalenia jej MyOnItemSelectedListener co sekundę, aby aplikacja odliczała się dynamicznie, a nie tylko po zainicjowaniu metody onCreate. Jeśli istnieje bardziej skuteczna metoda, a następnie szybko odpalam MyOnItemSelectedListener, byłbym wdzięczny za krytykę.Android - chcesz, aby aplikacja co sekundę wykonywała zadania

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: Ten awarii aplikacji i przynosi to się w LogCat gdy onCreate() jest wywoływana.

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)

Odpowiedz

17

spróbuje użyć UpdateDisplay funkcja jak poniżej:

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 
} 

Wreszcie, należy zadzwonić updateDisplay() w funkcji onCreate().
Mam nadzieję, że ten kod pomoże ci dokończyć to, co chcesz!

+0

Dziękujemy! Dodałem kod runOnUiThread() i uruchomiłem go. Nie jestem pewien, jak intensywne będzie to małe zadanie i czy jest to złe kodowanie, ale w tym celu wydaje się działać. –

+0

Oh. Powinieneś zwrócić uwagę na wątek tła i wątek interfejsu użytkownika. W tym przypadku potrzebujesz wątku interfejsu użytkownika do aktualizacji tekstu daty aktualizacji. A obiekt Timer jest najlepszym wyborem. Jeśli chcesz zaktualizować procent wątku pobierania, musisz użyć obiektu Handler. Google ma wiele przykładów: D – NamLe

0

Można użyć sendMessageAtTime() lub postAtTime() wysłać do siebie wiadomość drugi w przyszłości, a następnie go obsłużyć.

For more information.

0

Aby uruchomić go w głównym wątku:

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