Update des Homescreens bei zeitintensiven Methoden

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Update des Homescreens bei zeitintensiven Methoden

    Hallo Profis

    Wie ich ausgetestet habe, wird bei folgendem (Pseudo-)Code der Toast gar nicht angezeigt:

    Quellcode

    1. ... onCreate ... {
    2. Toast
    3. 10-sekündige Rechenaufgabe
    4. }
    Offensichtlich updatet Android den Bildschirm erst NACH dem vollständigen Abarbeiten der rechenintensiven dritten Zeile, und bis dann ist der Toast vorbei. Wie kann man den Toast doch anzeigen lassen? Gibt es (wie z.B. in VisualBasic Dot-Net mit DoEvents) einen Befehl, der die Ausführung einer Methode unterbricht und alle anstehenden Aktualisierungen des Homescreens vornimmt? Oder muss ein eigener Thread gestartet werden? Was ist der billigste Weg zum Ziel?

    Danke für jeden Tipp.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Desperate ()

  • Hallo Jogimuc

    Danke für den Tipp. Das wäre Neuland für mich, und ich weiss nicht, ob Threads das Problem auch lösen würde. Drum noch ein paar Details: Der Toast ist eigentlich nur eine Bestätigung, dass man die zeitintensive Berechnung tatsächlich ausgelöst hat (Mitteilung "Bin jetzt am Rechnen..."). Wenn der Toast erst zusammen mit dem Rechenresultat angezeigt wird, ist er absolut sinnlos. Leider braucht es auch das Resultat, um im Programm weiterzufahren, d.h. der Main Thread müsste auf das Ende des Nebenthreads warten. Könnte man stattdessen nicht den Toast in den Nebenthread auslagern? Dann könnten beide Threads gleichzeitig (genau genommen im Time Sharing) ausgeführt werden? Kann dieser Toast aber im Hauptthread angezeigt werden (Context = ?) ?
  • Also ein Toast kann nur im Main Thread angezeigt werden. Wenn du in einem Thread auf deinem Bildschirm was ausgeben willst wirst du einen Fehler bekommen. Ausgaben auf GUI Elemente müssen in Main Thread erfolgen.
    Mache einfach deinen Toast und starte einfach den Thread. Du kannst ja auch auf den Thread warten. Ob da ein einfacher Toast sinnvoll ist na ja kommt auf die Zeit an.

    Quellcode

    1. Toast.makeText(getApplicationContext(),"Zeit läuft",Toast.LENGTH_LONG).show();
    2. Thread t1 = new Thread() {
    3. public void run() {
    4. for (int i = 0; i < 1000000; i++) {
    5. }
    6. }
    7. };
    8. t1.start();
    9. try {
    10. t1.join();
    11. // Code der hier steht wird abgearbeitet, wenn der Thread fertig ist.
    12. } catch (InterruptedException e) {
    13. // Thread wurde abgebrochen
    14. }
    Alles anzeigen
    Ein Feedback auf Tipps ist auch schön. :P
  • Hallo yogimuc

    Hab deinen Vorschlag mit einem Thread t1 für die zeitintensive Rechnung realisiert, funktioniert aber auch nicht. Der Toast im Hauptthread findet während des Wartens des Hauptthreads auf das Ende des Nebenthreads t1 statt (genauso wie in Posting #1), und da der Homescreen ja erst am Ende updatet, sieht man das nicht mehr. Wenn ich in deinem Code die obere Grenze für i verkleinere, sehe ich tatsächlich noch die letzten Zehntelssekunden des Toasts.

    Ganz abgesehen davon scheint mir, dass da mit Kanonen auf Spatzen geschossen werden. Gibt es tatsächlich keine (einfache) Lösung für das sicher nicht seltene Problem, einen User zu informieren, dass das Smartphone nicht abgestürzt, sondern am Rechnen ist, wenn es die nächsten paar Sekunden nicht reagiert?
  • Dann versuche es mal so.

    Quellcode

    1. public void onClick(View view) {
    2. Toast.makeText(getApplicationContext(),"Start",Toast.LENGTH_SHORT).show();
    3. Thread t1 = new Thread() {
    4. public void run() {
    5. for (int i = 0; i < 1000000000; i++) {
    6. }
    7. runOnUiThread(new Runnable() {
    8. @Override
    9. public void run() {
    10. Toast.makeText(MainActivity.this,"ende",Toast.LENGTH_SHORT).show();
    11. }
    12. });
    13. }
    14. };
    15. t1.start();
    16. }
    Alles anzeigen


    So wird nicht in der onClick Methode gewartet.
    Wenn du aber im Thread eine Ausgabe machen willst also auf den UI Threadzugreifen willst, kannst du das für einfache aufgaben mit „runOnUiThread“ machen für größere Sachen würdeich einen Handler empfehlen. Auch würde ich dann für den Thread eine eigeneKlasse benutzen.
    Für größere Sachen würde ich vielleicht auch eine Progress Bar einsetzen, undkeinen Toast.
    Die Progress dann natürlich auch in einen Thread.
    Was genau machst du in der zeit schleife?
    Wie macht du denn weiter?
    Ist denn der UI in der Zeit Blockiertund wie übergibst du das Ergebnis?
    Ein Feedback auf Tipps ist auch schön. :P
  • Hallo jogimuc

    Dein (mir bis jetzt unbekannter) Hinweis, dass man mittels runOnUiThread doch von einem Nebenthread einen Toast auf den Homescreen ausgeben kann, war der Schlüssel zum Erfolg. Ich konnte die ganze zeitintensive Rechnerei in den Nebenthread auslagern, vor dessen Ausführung aber auch meinen Toast loswerden und nach der Rechnerei allfällige Fehler-Toasts - alles wie gewünscht. Danke ein weiteres Mal für deinen unschätzbaren Input.

    Und danke auch an alle, die sich mit dem Problem befasst haben, auch wenn sie keine oder keine "billigere" Lösung wussten.