2014-02-12 19 views
5

Ich möchte beginnen, zwei Zeilen Code alle 5 Sekunden zu wiederholen, wenn ich den Knopf START drücke und es schließe, wenn ich den Knopf STOP drücke. Ich habe versucht, mit einer TimerTask und Handles, aber konnte nicht herausfinden, wie.Android - Schleife Teil des Codes alle 5 Sekunden

public class MainActivity extends Activity { 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


      //final int i; 
      final TextView textView = (TextView) findViewById(R.id.textView); 
      final Button START_STOP = (Button) findViewById(R.id.START_STOP); 
      final ImageView random_note = (ImageView) findViewById(R.id.random_note); 
      final int min = 0; 
      final int max = 2; 
      final Integer[] image = { R.drawable.a0, R.drawable.a1,R.drawable.a2 }; 



     START_STOP.setTag(1); 
     START_STOP.setText("START"); 


     START_STOP.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
      int status = (Integer) v.getTag(); 
      if (status ==1) { 
       textView.setText("Hello"); 
       START_STOP.setText("STOP"); 
       v.setTag(0); 

       final Random random = new Random(); 

           //************************************************************ 
       // I would like to loop next 2 lines of code every 5 seconds.// 

           int i = random.nextInt(2 - 0 + 1) + 0; 
       random_note.setImageResource(image[i]); 

       //************************************************************ 
        } 

      else 
      { 
       textView.setText("Bye"); 
       START_STOP.setText("Let's PLAY!"); 
       v.setTag(1); 
      } 


      } 
     });  

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 


} 
+1

Was hat nicht mit der TimerTask funktioniert? –

+0

Ich weiß es nicht. Als ich versuchte, es auf dem Emulator auszuführen, stürzte es ab. Aber wahrscheinlich habe ich etwas falsch gemacht, da ich ein Android (Java) Anfänger bin. – Damijan

Antwort

18

Die Verwendung eines CountDownTimer wie in einer der anderen Antworten ist eine Möglichkeit, dies zu tun. Eine andere Möglichkeit wäre, einen Handler und die postDelayed Methode zu verwenden:

private boolean started = false; 
private Handler handler = new Handler(); 

private Runnable runnable = new Runnable() {   
    @Override 
    public void run() { 
     final Random random = new Random(); 
     int i = random.nextInt(2 - 0 + 1) + 0; 
     random_note.setImageResource(image[i]); 
     if(started) { 
      start(); 
     } 
    } 
}; 

public void stop() { 
    started = false; 
    handler.removeCallbacks(runnable); 
} 

public void start() { 
    started = true; 
    handler.postDelayed(runnable, 2000);   
} 

Hier ist ein Beispiel ein Timer und eine Timertask mit:

private Timer timer; 
private TimerTask timerTask = new TimerTask() { 

    @Override 
    public void run() { 
     final Random random = new Random(); 
     int i = random.nextInt(2 - 0 + 1) + 0; 
     random_note.setImageResource(image[i]); 
    } 
}; 

public void start() { 
    if(timer != null) { 
     return; 
    } 
    timer = new Timer(); 
    timer.scheduleAtFixedRate(timerTask, 0, 2000); 
} 

public void stop() { 
    timer.cancel(); 
    timer = null; 
} 
+1

Ich habe in meinen Apps immer einen CountDownTimer verwendet, um die Banner in einer Aktivität alle 5 Sekunden zu ändern. Was ist der beste Weg, um eine Aktion alle 5 Sekunden zu wiederholen, der CountDownTimer oder der Handler und postDelayed? – Giacomoni

+0

Danke. Wo würdest du das in meinen ursprünglichen Code einfügen? – Damijan

+2

Gute Frage giacomoni! Ich habe mir den CountDownTimer angeschaut und intern einen Handler verwendet: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/os/CountDownTimer .java # 109 Ich denke, sie sind mehr oder weniger gleichwertig. Der Timer verwendet einen TimerThread mit einer Warteschlange von TimerTasks: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java#460 Es ist schwer um zu sagen, welches besser ist. Ich weiß nicht genug über die Unterschiede zwischen Threads und Handlern, um Ihnen eine gute Antwort zu geben. – britzl

12

Sie CountDownTimer wie das folgende Verfahren verwenden:

private CountDownTimer timer; 

timer = new CountDownTimer(5000, 20) { 

    @Override 
    public void onTick(long millisUntilFinished) { 

    } 

    @Override 
    public void onFinish() { 
     try{ 
      yourMethod(); 
     }catch(Exception e){ 
      Log.e("Error", "Error: " + e.toString()); 
     } 
    } 
}.start(); 

Und dann wieder den Timer zu nennen:

public void yourMethod(){ 
    //do what you want 
    timer.start(); 
} 

den Timer abzubrechen, können Sie anrufen timer.cancel();

Hoffe es hilft!

+0

Hallo Herr, kann der obige Code verwendet werden, um eine Aktivität zu aktualisieren, bis der Benutzer auf die Schaltfläche zurück klickt ...? –

0

Ich habe nicht viel hinzuzufügen, außer zu erwähnen die Unterschiede zwischen Handler, CountDownTimer und regulärem Timer. Wie erwähnt, verwendet der CountDownTimer intern einen Handler, so dass der Handler direkt verwendet wird. Ein Handler wird verwendet, um Ui-Zeug für sehr kurze Zeitabschnitte zu laufen. Ein Beispiel wäre setText für eine Textansicht. Bei rechenintensiven Aufgaben können die Handler eine Verzögerung verursachen. Ein Timer kann auch nur kurze Aufgaben ausführen, aber es ist nicht unbedingt nur für UI-Sachen. Für kompliziertere Aufgaben sollte ein neuer Thread verwendet werden.

2

können Sie RxJava2/RxAndroid2 verwenden und eine beobachtbare erstellen, die eine Nachricht mit Pseudo-Code in jeder Sekunde (oder was auch immer Sie wollen), Beispiel emittiert:

Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS) 
      .timeInterval() 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Consumer<Timed<Long>>() { 
       @Override 
       public void accept(@NonNull Timed<Long> longTimed) throws Exception {    
        //your code here. 
        Log.d(TAG, new DateTime()); 
       } 
      }); 

Wenn Sie es stoppen möchten, können Sie einfach anrufen :

timer.dispose(); 

Ich finde diesen Code viel lesbarer als die anderen Optionen.