TextView, dynamischer Wert aus einem Thread

  • Zuerst möchte ich alle herzlich Begrüßen!


    Ich möchte gerne in TextView dynamisch je 1 Sekunde den Wert ändern. Dies soll in einer Classe passieren in der eine run() Methode implementiert ist.


    Classe:


    In einer zweiten Classe sind nur die Methoden:



    Hier die MainActivity


    Mein Problem ist folgender, egal was ich auch versuche erhalte ich immer eine NullPointerException. Ist die Umsetzung auf die gewählte Art überhaupt möglich? In den Classen ist zur Zeit keine weitere Implementierung des TextView bis auf Deklaration des TextViews und Zuweisung der ID aus der activity_main.


    Danke schön!


    P.S Ich bin leider noch ein Anfänger!

  • Hoi,


    vll fehlt mir Kaffee, aber so ganz kapieren tu ich deinen Code grad nicht bzw. mir fällt grad nicht auf, wo genau die NullPointerException auftreten sollte. Hättest du da den LogCat Auszug?



    Ich hinterfrag einfach mal bisschen was.

    Java
    public void onStopTrackingTouch(SeekBar seekBar) {
    				Functions f = new Functions();
    				f.setTime(time);
    				Counter setDataCounter = new Counter();
    				setDataCounter.setTime(f);
    				Thread threadCounter = new Thread(setDataCounter);
    				threadCounter.start();
    
    
    			}


    Die Methode ist innerhalb der Klasse Functions, warum genau erzeugst du da drin eine neue Instanz von Functions? Probier mal anstatt f.setTime Functions.this.setTime und versuche auch die anderen aus zu tauschen.


    Zu dem Code-Snippet

    Java
    while (timeCounter-- > 0) {
    			try {
    				Thread.sleep(1000);
    				// Kann ich hier überhaupt den Wert das TextView übergeben?
    			} catch (InterruptedException e) {
    				// TODO do what
    				e.printStackTrace();
    			}
    		}


    kann ich dir sagen, man kann UI-Elemente nur aus dem Mainthread heraus verändern. Lässt sich mithilfe der Klasse Handler umgehen.

    Java
    // Get a handler that can be used to post to the main thread
    Handler mainHandler = new Handler(context.getMainLooper());
    
    
    Runnable myRunnable = new Runnable(...); // This is your code
    mainHandler.post(myRunnable);


    Vll. kommen wir der Lösung ja auf diesem Wege etwas näher ;) der LogCat Auszug wär aber auf jeden Fall noch interessant.



    Gruß,
    Matze

  • Hallo matthias,


    zuerst bedanke ich mich für Deine Antwort. Ich habe etwas aufgeräumt und die Klasse Counter entfernt. Habe ich es richtig verstanden, dass der Handler die Möglichkeit bietet etwas in die GUI zu indizieren nach dem der Objekt der MainActivity bereits erstellt worden ist? Sorry aber irgend wie blicke ich da nicht durch :(


    Anbei der gesamte Code der beiden Klassen, was ich erreichen möchte ist, dass nach Update der Seekbar im TextView die Zeit alle 1000ms aktualisiert.




    Danke schön für die Unterstützung!!

  • Hoi,


    füge mal deinem SeekbarChangedListener folgendes hinzu

    Java
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
         mytext.setText(progress); 
    }


    Das müsste dazu führen, dass die TextView immer denselben Wert zeigt, den die SeekBar gerade hat. Warum genau willst du alle 1s aktualisieren, wenn die Seekbar sowieso informiert, wenn sie sich ändert?


    In dem Fall braucht man wie ich das sehe auch keinen Handler, da das eine anonyme Klasse innerhalb der MainActivity ist. Einen Handler bräuchte man erst dann, wenn man sich innerhalb eines anderen Threads befindet und somit nicht mehr innerhalb der Activity, die das Objekt hält bzw. auch anzeigt. Android lässt solche Manipulationen nicht zu.



    Gruß,
    Matze

  • Hallo Matze,


    danke für den Tipp, ich teste es sobald ich zu hause bin.


    Frage mich bitte nicht nach dem Sinn der Sache ;) Ich habe es so geplant und lasse nicht nach bis es funktioniert ;)
    Ich möchte mich in das Thema einarbeiten.


    Vielen Dank! Ich melde mich sobald es funktioniert.


    Vg deralte

  • Hallo Matze,


    leider kommt es hierbei zum gleichen Problem in der onProgressChanged() kann ich das TextView nicht ansprechen.
    Ich habe jetzt den Statusbalken dynamisch gemacht seekbar.setProgress(mytime), so sieht es auch gut aus. Was ich nicht verstehe ist folgendes, wenn die Zeit läuft kann ich z.B mit einen Button den TextView ändern, liegt wohl dran dass ich auf den Thread zugreife?


    Sehe ich das richtig?


    Danke schön!


    VG deralte

  • Hoi,


    sorry, dass ich erst jetzt antworte ... bissl stressig momentan.


    Wenn sich die UI nicht verändert, obwohl sie es sollte, wird meistens im MainThread irgendwas aufwändigeres gemacht, das dann die UI blockiert. Hatte ich neulich z.B. bei einem SplashScreen, der so lange angezeigt werden sollte, bis diverse Inhalte aus dem Netz geladen wurden, dazu ein Progress Drehrädchen. Habe ich alles im MainThread gemacht, wurde nichtmal das Hintergrundbild geladen sondern nur ein weißer Screen und nach 2-3 Sekunden die nächste Activity ....


    Habs im Endeffekt so gelöst:
    Interface mit callback-Methode erstellt und im SplashScreen implementiert. Die Implementierung enthält nur das Starten der nächsten Activity. In der onCreate des SplashScreens starte ich einen AsyncTask, der this mit bekommt und in der onPostExecute den Callback aufruft. Schon läuft alles das Zeitaufwändig ist in einem AsyncTask, der MainThread hat komplett überhaupt nichts zu tun und wird irgendwann aufgerufen, wenn der AsyncTask fertig ist ....


    Vll. lässt sich das ja irgendwie auf dein Szenario übertragen.
    Verrückte Idee wär, wenn du einen AsyncTask hättest, der in der onPostExecute einen Wert aus den SharedPreferences holt, in der doInBackground nur eine Sekunde oder so wartet, in der onPostExecute dann schaut, ob der Wert schon z.B. 100 erreicht hat, wenn nicht um 1 hoch zählen, in die SharedPreferences speichern, den progress hoch setzen und sich selbst erneut aufrufen ... keine Ahnung ob das funktionieren würde aber den Grundgedanke find ich grad amüsant ;)



    Gruß,
    Matze

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!