Zugriff von Ticker/Timer-Klasse auf TextView-Objekt

  • 3 Antworten
  • Letztes Antwortdatum
S

stdevel

Neues Mitglied
0
Hallo!

Ich portiere derzeit einen von mir in Java entwickelten Prüfungssimulator auf Android - funktioniert soweit eigentlich auch gut.

Derzeit habe ich mit der Umsetzung eines Timers ein wenig Probleme. Der Timer wird in der Software verwendet, um ein festgelegtes Zeitlimit herunter zu zählen. Es ist also ein Timer, mit einem TimerTask, der einen Zähler sekündlich heruntersetzt und ein TextLabel neu beschriftet.

In Android soll er natürlich das gleiche mit einem TextView machen. Das Problem ist, dass ich da irgendwo wahrscheinlich ein Rechteproblem habe. Mittels Log.d(tag, msg) kann ich die Texte ausgeben, aber nicht auf das TextView anwenden. Nach einer Textänderung bricht das Programm ab, im Debug finde ich auch nichts.

Anbei der Quellcode:

Code:
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class frage extends Activity {
    
    //Klassen-Tag generieren
    private static final String tag = "frage";
    private questionCatalog catalog;
    
    //Timer-Variablen
    private int mins, secs, tempTime;
    Timer ticker;            //Countdown-Ticker Timer
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //Layout setzen und Intent-Extras beziehen
        setContentView(R.layout.frage);
        final Bundle extras = getIntent().getExtras();
        
        //Wenn ein Dateiname übertragen wurde, diesen Loggen und einen Fragenkatalog instanzieren
        if(extras != null && extras.getString("dateiname").length() > 0) {
            Log.d(tag, "Got filename (" + extras.getString("dateiname") + ") from previous activity.");
            catalog = new questionCatalog(extras.getString("dateiname"));
        }
        else
        {
            Log.d(tag, "Got no file name");
            Toast.makeText(this, "Keine Datei", Toast.LENGTH_LONG).show();
            this.finish();
        }
        
        //Elemente deaktiveren, damit sie später dynamisch aktivieren werden können
        ScrollView  radGrp = (ScrollView) findViewById(R.id.scr_frageRad);
        radGrp.setVisibility(View.GONE);
        ScrollView  chkGrp = (ScrollView) findViewById(R.id.scr_frageChk);
        chkGrp.setVisibility(View.GONE);
        //TextView timer = (TextView) findViewById(R.id.txt_zeit);    
        //timer.setVisibility(100);
        
        //Timer instanzieren und starten
        ticker = new Timer();
        ticker.schedule(new Ticker(10*60), 0, 1000);
        
    }
    
    
    
    class Ticker extends TimerTask
    /* Ticker-Task zum Runterzaehlen der Zeit */
    {
        
        //Variablendeklarationen
        private int seconds;
        private TextView testObj = (TextView) findViewById(R.id.txt_zeit);
        
        Ticker(int seconds)
        /* Konstuktor */
        { this.seconds = seconds; }
        
        public void run()
        /* Hauptprozedur */
        {
            //Verbleibende Zeit formatiert ausgeben --> Anzahl der verbleibenden Minuten beziehen
            //tempTime = seconds/60;
            
            //Verbleibende Minuten (+Sekunden) setzen, falls vorhanden
            /*if(tempTime != 0)
            {
                mins = tempTime;
                secs = seconds - (mins*60);
            }
            else
            {
                mins = 0;
                secs = seconds;
            }*/
            
            //Log.d("bla", temp.getText().toString());
            
            //Zeit ausgeben, bei weniger als 10 Sekunden 0 voranstellen
            /*if(secs < 10) { temp.setText(mins + ":" + "0" + secs); }
            else { temp.setText(mins + ":" + secs); }*/
            
            testObj.setText(testObj.getText() + ".");
            
            //Sekunden verringern
            //seconds--;
        }
    }

}
Ich sehe wahrscheinlich einfach den Wald vor lauter Bäume nicht mehr. :D Vielleicht weiß ja einer von Euch Rat.

Danke Euch im Voraus.

Grüße! ;)
 
Hallo,

es scheint, ich habe das Problem selbst gelöst. :D

Das Problem ist - dass TimerTasks unter Android nicht die korrekte Wahl für mein Problem ist. Laut den folgenden Webseiten macht ein Handler mehr Sinn:


Und siehe da - so funktioniert das Ganze.

Der überarbeitete Quellcode lautet wie folgt (falls einer das Problem nachvollziehen und ggf. nachbauen möchte):

Code:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class frage extends Activity {
    
    //Klassen-Tag generieren
    private static final String tag = "frage";
    private questionCatalog catalog;
    
    //Timer-Variablen
    private int seconds, mins, secs, tempTime;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //Layout setzen und Intent-Extras beziehen
        setContentView(R.layout.frage);
        final Bundle extras = getIntent().getExtras();
        
        //TextView, Handler und Runnable instanzieren
        final TextView timer = (TextView) findViewById(R.id.txt_zeit);
        final Handler mHandler = new Handler();
        final Runnable mUpdateTimeTask = new Runnable() {
               public void run() {

                   //Verbleibende Zeit formatiert ausgeben --> Anzahl der verbleibenden Minuten beziehen
                   tempTime = seconds/60;
                   
                   //Verbleibende Minuten (+Sekunden) setzen, falls vorhanden
                   if(tempTime != 0)
                   {
                       mins = tempTime;
                       secs = seconds - (mins*60);
                   }
                   else
                   {
                       mins = 0;
                       secs = seconds;
                   }
                   
                   //Zeit ausgeben, bei weniger als 10 Sekunden 0 voranstellen
                   if(secs < 10) { timer.setText(mins + ":" + "0" + secs); }
                   else { timer.setText(mins + ":" + secs); }
                    
                    //Sekunden verringern
                    seconds--;
                   
                   //Handler in 1 Sekunden neustarten
                   mHandler.postDelayed(this, 1000);
               }
            };
        
        //Wenn ein Dateiname übertragen wurde, diesen Loggen und einen Fragenkatalog instanzieren
        if(extras != null && extras.getString("dateiname").length() > 0) {
            Log.d(tag, "Got filename (" + extras.getString("dateiname") + ") from previous activity.");
            catalog = new questionCatalog(extras.getString("dateiname"));
        }
        else
        {
            Log.d(tag, "Got no file name");
            Toast.makeText(this, "Keine Datei", Toast.LENGTH_LONG).show();
            this.finish();
        }
        
        //Elemente deaktiveren, damit sie später dynamisch aktivieren werden können
        ScrollView  radGrp = (ScrollView) findViewById(R.id.scr_frageRad);
        radGrp.setVisibility(View.GONE);
        ScrollView  chkGrp = (ScrollView) findViewById(R.id.scr_frageChk);
        chkGrp.setVisibility(View.GONE);
        
        //TextView timer = (TextView) findViewById(R.id.txt_zeit);    
        //timer.setVisibility(100);
        
        //Timer instanzieren und starten
        seconds = 120;
        mHandler.removeCallbacks(mUpdateTimeTask);
        mHandler.post(mUpdateTimeTask);
        
    }

}

Danke dennoch an Euch alle. :)

Grüße ;)
 
Ich vermisse da irgendwo eine Abbruchbedinung in der run() Methode..
ansonsten braucht deine App noch schön CPU Last, wenn der User schon wieder auf dem Homescreen ist. ;)
 

Ähnliche Themen

D
Antworten
8
Aufrufe
744
jogimuc
J
Zurück
Oben Unten