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

Globale TextView Variable

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von swa00, 29.03.2011.

  1. swa00, 29.03.2011 #1
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    Hallo liebe Gemeinde,

    ich entwickle zwar schon über 20 Jahre in C++ aber bei so manchen Dingen im Android SDK bekomme ich nicht so hin , wie ich mir das vorstelle :)

    Ich habe das Problem ,dass ich in Timer Routinen oder einem Thred keinen Zugriff mehr auf eine TextView Variable habe, warum nicht ? ( null)


    mach ich folgendes bei einem Callback des GPS sensors
    TextView tview = (TextView) findViewById(R.id.textfeld);
    tview.setText("Bla Bla");
    alles Prefekt !!!


    Habe ich z.b einen Timer
    class UpdateTimeTask extends TimerTask
    {
    public void run()
    {
    long millis = System.currentTimeMillis() - 200;
    int seconds = (int) (millis / 1000);
    int minutes = seconds / 60;
    seconds = seconds % 60;
    TextView tview = (TextView) findViewById(R.id.textfeld);
    tview.setText("Bla bla");
    }
    }

    oder in einem Thread
    @Override
    public void run()
    {
    try
    {

    while(true)
    {
    sleep(1000);
    TextView tview = (TextView) findViewById(R.id.textfeld);
    tview.setText("Bla Bla");

    }
    }
    catch(InterruptedException e){}
    }



    dann bekomme ich einen Vollabsturz beim zugriff auf den TextView
    Den gibt es einfach nicht

    Ich kann machen was ich will , also Globale variable , local etc etc .. immer in einem Thread oder in einem Time habe ich keinen Zugriff mehr auf Texview

    Warum ist das so, oder was mache ich grundsätzlich falsch in meinem Überlegungen ?

    Vielen lieben Dank mal im Voraus für euere Antworten
    lg
    Stefan

    gegeben : Android SDK unter Eclipse
     
  2. GalaxyKeks, 29.03.2011 #2
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Wie lautet denn die Fehlermeldung?
    Vielleicht kannst du mal den Stacktrace posten und die dort verlinkten Zeilen...
     
  3. swa00, 29.03.2011 #3
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    Hi Galaxy,

    danke für deine schnelle Antwort und schon hast du mich auf dem mega falschen Fuss erwischt :)

    Wie erstelle ich den von dir erwünschten Stacktrace unter Eclipe ?

    lg
    Stefan
     
  4. GalaxyKeks, 29.03.2011 #4
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
  5. swa00, 29.03.2011 #5
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): FATAL EXCEPTION: Thread-8
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.view.View.invalidate(View.java:5139)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.widget.TextView.checkForRelayout(TextView.java:5364)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.widget.TextView.setText(TextView.java:2688)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.widget.TextView.setText(TextView.java:2556)
    03-29 08:53:23.337: ERROR/AndroidRuntime(660): at android.widget.TextView.setText(TextView.java:2531)


    Sagt das was ? :)


    P.S danke für die Newbie unterstüzung :)
     
  6. GalaxyKeks, 29.03.2011 #6
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Kein Thema, jeder fängt mal an ;)
    Ist das alles was der ausspuckt?

    Und noch eine andere Frage:
    Warum hast du
    Mit in der Schleife? reicht doch das einmal da drüber raus zu holen, da ändert sich ja nichts...

    Und beide Varianten gehen nicht?
     
  7. swa00, 29.03.2011 #7
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    also ich portioniere mal , damit es übersichtlicher wird ..

    innerhalb public void onCreate(Bundle savedInstanceState)
    {
    ... bla bla bla init
    // Mal nen Test .... geht
    TextView tview = (TextView) findViewById(R.id.textfeld);
    tview.setText("Hallo");

    // thread starten
    StartCalculateThread();

    }


    // hier der Thread
    //////////////////////////////////////
    public void StartCalculateThread()
    {
    // thread für die Berechnung
    Thread CalculateThread = new Thread()
    {
    @Override
    public void run()
    {

    TextView tview = null;
    tview = (TextView) findViewById(R.id.textfeld);
    try
    {
    while(true)
    {
    sleep(1000);
    tview.setText("Bla Bla");

    }
    }
    catch(InterruptedException e){}
    }
    };
    CalculateThread.start();
    /////////////////////////////

    Die Stacktrace zeilen habe ich natürlich erst ab der Exception herauskopiert - bin nicht davon ausgegangen , dass du das ganze geraffel haben wolltest :)

    lg
     
  8. GalaxyKeks, 29.03.2011 #8
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Dein
    wäre noch interessant, weil du das ContentView setzten musst.

    Wegen dem Logcat ist, wollte nicht alles ;)
    Aber wundert mich das der nirgends auf deinen Code verweist...
     
  9. garak, 29.03.2011 #9
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Das ist doch ziemlich eindeutig. Wenn du einen TimerTask erstellst, bekommst du einen neuen Thread und der kann nicht auf ein View eines anderen Threads zugreifen. Abhilfe könnte schaffen das TextView als public static zu deklarieren und über die Startklasse darauf zuzugreifen, aber ob das funktioniert musst du selber herausfinden:

    Code:
    public class StartKlasse extends Activity {
      public static TextView tview;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tview = (TextView) findViewById(R.id.textfeld);
        ...
      }
      ....
    }
    
    ////////////////////////
    
    class UpdateTimeTask extends TimerTask {
       public void run() {
          ...
          StartKlasse.tview.setText("Bla bla");
       }
    }
    
     
  10. swa00, 29.03.2011 #10
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011

    Übrigens - zur Info : Das geht also der Callback des Sensors











    DU HAST ES GEWOLLT :)


    03-29 09:28:08.277: DEBUG/AndroidRuntime(359): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
    03-29 09:28:08.277: DEBUG/AndroidRuntime(359): CheckJNI is ON
    03-29 09:28:08.498: DEBUG/AndroidRuntime(359): --- registering native functions ---
    03-29 09:28:09.366: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.streetlimit/.StreetLimit }
    03-29 09:28:09.468: DEBUG/AndroidRuntime(359): Shutting down VM
    03-29 09:28:09.487: INFO/ActivityManager(59): Start proc com.example.streetlimit for activity com.example.streetlimit/.StreetLimit: pid=365 uid=10040 gids={}
    03-29 09:28:09.507: DEBUG/dalvikvm(359): Debugger has detached; object registry had 1 entries
    03-29 09:28:09.597: INFO/AndroidRuntime(359): NOTE: attach of thread 'Binder Thread #3' failed
    03-29 09:28:09.817: DEBUG/dalvikvm(33): GC_EXPLICIT freed 270 objects / 10312 bytes in 265ms
    03-29 09:28:09.967: DEBUG/dalvikvm(33): GC_EXPLICIT freed 32 objects / 1408 bytes in 101ms
    03-29 09:28:10.268: DEBUG/dalvikvm(33): GC_EXPLICIT freed 2 objects / 64 bytes in 302ms
    03-29 09:28:10.606: WARN/GpsLocationProvider(59): Duplicate add listener for uid 10040
    03-29 09:28:11.077: INFO/ActivityManager(59): Displayed activity com.example.streetlimit/.StreetLimit: 1604 ms (total 1604 ms)
    03-29 09:28:11.566: WARN/dalvikvm(365): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): FATAL EXCEPTION: Thread-8
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.view.View.invalidate(View.java:5139)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.widget.TextView.checkForRelayout(TextView.java:5364)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.widget.TextView.setText(TextView.java:2688)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.widget.TextView.setText(TextView.java:2556)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at android.widget.TextView.setText(TextView.java:2531)
    03-29 09:28:11.566: ERROR/AndroidRuntime(365): at com.example.streetlimit.StreetLimit$2.run(StreetLimit.java:213)
    03-29 09:28:11.598: WARN/ActivityManager(59): Force finishing activity com.example.streetlimit/.StreetLimit
    03-29 09:28:17.418: DEBUG/dalvikvm(188): GC_EXPLICIT freed 242 objects / 16144 bytes in 67ms
    03-29 09:28:22.487: DEBUG/dalvikvm(262): GC_EXPLICIT freed 2070 objects / 148040 bytes in 95ms
     
  11. GalaxyKeks, 29.03.2011 #11
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Versuch mal Garak's Ansatz, da wollte ich übrigens auch drauf hinaus ;)
    Du kannst auch ne "Holder-klasse" machen die all das als statische Elemente enthält.
    Ist im Prinzip das bloß ausgelagert.

    Der Fehler schein von hier : StreetLi mit.java:213 zu kommen.
     
  12. swa00, 29.03.2011 #12
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    Halllo Garak,

    danke für Deine Idee...



    Ich habe s ausprobiert - leider mit dem gleichen Ergebnis ..
    Zumal der Thread innerhalb der activity ( oder timer) deklariert ist :-(
     
  13. swa00, 29.03.2011 #13
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    Jaaaaaa, ich weis ich nerve .. ne Holder klasse habe ich auch schon hinter mir ....

    iste s denn überhaupt richtig , innerhalb der activity alles zu deklarieren ? ich bin im prinzip dadurch gar nicht auf garaks idee gekommen ....
     
  14. garak, 29.03.2011 #14
    garak

    garak Ehrenmitglied

    Beiträge:
    8,270
    Erhaltene Danke:
    4,794
    Registriert seit:
    12.12.2009
    Doch vom Android-Gedanken her schon. Hast du die Timerklasse mal als innere Klasse deines Activities versucht?

    Nachtrag: Als innere Klasse funktioniert es:
    Code:
    public class Test extends Activity {
    
      private TextView textView1;
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView1 = (TextView) findViewById(R.id.textView1);
        new TestThread().start();
      }
      class TestThread extends Thread {
        @Override
        public void run() {
          textView1.setText("Bla bla");
        }
      }
    }
    
     
    swa00 bedankt sich.
  15. swa00, 29.03.2011 #15
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    Moderation: Nicht den ganzen vorherigen Beitrag zitieren!

    soooo, da habe ich jetzt ausprobiert .. negativ

    ich frage mal am besten ganz anders - im prinzip möchte ich ja nur alle x sekunden ein Update UI haben, welches daten aus einer Holder klasse anzeigt.


    In welche Richtung muss ich denn mal schauen um ein schönes Beispiel zu bekommen , im Prinzip ist das ja eigentlich ziemlich trivial , was ich vorhabe ..

    Lieben Dank
    Stefan
     
  16. GalaxyKeks, 29.03.2011 #16
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Vielleicht solltest du etwas banaler anfangen und dann das ganze erweitern wenn es funktioniert ;)
     
  17. swa00, 29.03.2011 #17
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    ich neige dazu , dir eben 100 Punkte für die Motivation zu vergeben :)
    Im Ernst - dass ich an der Hürde scheitere, einfach einen Text an eine simple stelle auszugeben, hätte ich mir nie erträumen lassen :)
     
  18. GalaxyKeks, 29.03.2011 #18
    GalaxyKeks

    GalaxyKeks Android-Guru

    Beiträge:
    2,004
    Erhaltene Danke:
    356
    Registriert seit:
    16.08.2010
    Phone:
    OnePlus3, Nexus 6P
    Ich helfe gern, bloß bin ich an der Arbeit und kann nichts testen... daher ist es mehr oder weniger "nur" Spekulation meinerseits.
    Generell kann ich dir aber zu so Problemen "Stackoverflow.com" empfehlen, bin da auch aktiv. Da wird auch immer gern und schnell geholfen! :)
     
    swa00 bedankt sich.
  19. swa00, 29.03.2011 #19
    swa00

    swa00 Threadstarter Android-Experte

    Beiträge:
    504
    Erhaltene Danke:
    103
    Registriert seit:
    21.03.2011
    LÖSUNG !!!!

    ok, ich bin diesem Forum temporär abtrünnig geworden und habe mich bei StackOverflow umgeshen.

    Dieses Beispiel ist die Lösung und sollte fairerweise diesem Forum nicht vorenthalten werden

    How to run a Runnable thread in Android? - Stack Overflow

    Fazit- ein Thread und ein Timer benötigt einen zusätzlichen Handler um auf Ui Elemente zuzugreifen .


    Garak & GalaxyKeks

    Vielen lieben Dank für eure Mühe !!!!!!


    lg
    Stefan
     

Diese Seite empfehlen

Besucher kamen mit folgenden Begriffen auf unsere Seite:

  1. android globale stringvariable declarieren