1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Zugriff von Ticker/Timer-Klasse auf TextView-Objekt

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von stdevel, 05.08.2011.

  1. stdevel, 05.08.2011 #1
    stdevel

    stdevel Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    05.08.2011
    Phone:
    HTC Desire HD
    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! ;)
     
  2. stdevel, 05.08.2011 #2
    stdevel

    stdevel Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    05.08.2011
    Phone:
    HTC Desire HD
    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 ;)
     
  3. Fr4gg0r, 05.08.2011 #3
    Fr4gg0r

    Fr4gg0r App-Anbieter (Werbung)

    Beiträge:
    2,506
    Erhaltene Danke:
    447
    Registriert seit:
    21.12.2009
    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. ;)
     
  4. stdevel, 11.08.2011 #4
    stdevel

    stdevel Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    05.08.2011
    Phone:
    HTC Desire HD
    Hi!

    Sorry für die späte Antwort - ja, da hast Du recht. Das Ganze war noch mehr ein unfertiges Code-Snippet. Die Abbruch-Bedingung gibt's natürlich. Danke aber nochmals für den Hinweis. :)

    Mein Simulator ist übrigens jetzt in einer ersten Version erschienen, siehe auch hier: http://www.android-hilfe.de/android...age-rankinguefungssimulators.html#post1826749

    :)

    Gruß!
     

Diese Seite empfehlen