keine TextView-Aktualisierung in der while-Schleife

G

Gast2

Gast
erst der Quelltext:
Java:
public class MainActivity extends Activity {

	TextView txv;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        txv = (TextView) findViewById(R.id.ausgabe);
        long now;

		while (true) {
			now = System.nanoTime();
			txv.setText(String.valueOf(now));
		}
    }
}

Was würdest Du erwarten?
Ich erwarte, dass ich kontinuierlich den aktuellen Timestamp angezeigt bekomme.
Aber der Bildschirm bleibt leer.

Egal, welchen Text ich in innerhalb der while-Schleife dem txv zuweise, er wird nicht angezeigt.
Wenn ich die while(){} auskommentiere, sehe ich den Originaltext.

Warum wird nichts angezeigt??? ???:L
 

schlingel

Gesperrter Benutzer
Ich würde erwarten, dass das System anzeigt, dass sich die App aufgehängt hat und mir einen Force-Close-Dialog anzeigen.

Warum du allerdings dorthin gar nicht kommst ist mir ein Rätsel. Wird die App wirklich aufgerufen? Aktuelle Version schon am Gerät/Emulator?
 
G

Gast2

Gast
Warum du allerdings dorthin gar nicht kommst ist mir ein Rätsel. Wird die App wirklich aufgerufen?

Ja. Ich habe den Quelltext geändert nach:
Java:
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        txv = (TextView) findViewById(R.id.ausgabe);
        
        long now = System.nanoTime();        
		long end = now + 2000000000;
		
		txv.setText("Anfang");
		
		while (System.nanoTime() < end ) {
			txv.setText(String.valueOf(now));
		}
		
		txv.setText("Ende");
    }

Nach zwei Sekunden weiser Bildschirm erscheint "Ende".
Ergo, das Programm läuft. Nur werden Textzuweisungen innerhalb der Schleife nicht gezeigt.
Übrigens auch nicht in do while oder if -Schleifen.
 
G

Gast2

Gast
Nun ja,

aber warum wird innerhalb der Schleife die Änderung der Werte nicht übernommen.
Dieses Problem habe ich schön öfters gesehen, aber keine Lösung dafür.

Schleifen kommen immer wieder vor und innerhalb der Schleifen sollten doch Anweisungen möglich sein, die sofort ausgeführt werden?!
 

schlingel

Gesperrter Benutzer
Folgendes (zugegebenermaßen blödes) Gleichnis:
- Du stehst im Wohnzimmer und winkst deiner Freundin. Deine Hand befindet sich im Wohnzimmer.
- Du stehst im Wohnzimmer und ziehst dir Handschuhe an und winkst. Ist deshalb deine Hand nicht mehr im Wohnzimmer?

Wenn du also ne Methode einer dritten Klasse innerhalb der onCreate-Methode aufrufst, bist du noch immer in der onCreate-Methode.
 
G

Gast2

Gast
Wenn du also ne Methode einer dritten Klasse innerhalb der onCreate-Methode aufrufst, bist du noch immer in der onCreate-Methode.

Ja genau!
Aber das gesamte Programm läuft doch in der onCreate-Methode,
es geht mal in eine andere Klasse
oder zieht sich auch mal Handschuhe an,
aber es verlässt doch die onCreate nie.
Außer das Programm ist zu Ende.

Ich habe überhaupt keine Vorstellung, wie etwas unabhängig von der onCreate laufen kann.

Hier noch so ein Beispiel:
Java:
public class MainActivity extends Activity implements OnClickListener {

	Button btn_start;
	TextView txv_text;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_start.setOnClickListener(this);
        
        txv_text = (TextView) findViewById(R.id.txv_p1_maincontend);
    }

	@Override
	public void onClick(View v) {
		for (int i = 0; i < 3; i++) {			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}					
			txv_text.setText("zählen");			
		}		
		txv_text.setText("ENDE");
	}	
}

Nach dem Button-Klick passiert drei Sekunden nichts und dann steht im TextView "ENDE".
(Statt "0", "1", "2", "ENDE")

Soll da wirklich nur ein zweiter Thread helfen??? ???:L
 
G

Gast2

Gast
Ich arbeite mich in den Thread Gedanken ein,
aber auch hier bekomme ich ein null-pointer-exception in Zeile 22:
Java:
public class MainActivity extends Activity {

	TextView text;
	String zahl;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        
        Runnable r = new Runnable(){

			@Override
			public void run() {
		        text = (TextView) findViewById(R.id.txv_info);
				for (int i = 0; i < 6; i++) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					zahl = String.valueOf(i);
					text.setText(zahl);	
				}			
			}        	
        };
        Thread t = new Thread(r);
        t.start();
    }
}
Den TextView habe ich testweise innerhalb und außerhalb deklariert,
text.setText() auch mit einfachen String belegt ("Hallo"),
alle Versuche waren ohne Erfolg.

Warum kann ich keinen Text zuweisen (und anzeigen) lassen?
 

VfL_Freak

Top Contributor
Moin,

vermutlich ist "text" gleich null !
Versuch's dochmal so:
Java:
public void run() 
{
    text = (TextView) findViewById(R.id.txv_info);
    if( text != null ) // !!!
    {
        for (int i = 0; i < 6; i++) 
        {
            try 
            {
                Thread.sleep(1000);
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
            zahl = String.valueOf(i);
            text.setText(zahl); 
    }
}

Gruß
Klaus
 

schlingel

Gesperrter Benutzer
Aber das gesamte Programm läuft doch in der onCreate-Methode[...]
Nein! Wie kommst du denn auf diese Idee?

Schau dir mal den Activity-Lifecycle an:

activity_lifecycle.png

onCreate ist nur die erste Methode die aufgerufen wird wenn die Activity erzeugt wird. Sobald die Activitiy dann läuft, reagiert sie einfach nur noch auf Events. Die können vom Benutzer kommen oder vom System, z.B. um die Activity zu beenden oder zu pausieren.

Die NPE bekommst du, weil du hier nicht das Layout für die Activity gesetzt hast. (Der Aufruf von setContentView fehlt) Abgesehen davon, würdest du gleich die nächste Exception bekommen wenn du versuchst aus einem anderen Thread als dem UI-Thread auf die UI zuzugreifen.

Dazu müsstest du das ganze so machen:

Java:
public class MainActivity extends Activity {
 
    TextView text;
    String zahl; // warum muss das eigentlich eine Instanzvariable sein?
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        
        setContentView(R.layout.deineContentView);
        text = (TextView) findViewById(R.id.txv_info);

        Runnable r = new Runnable(){
 
            @Override
            public void run() {
                for (int i = 0; i < 6; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    zahl = String.valueOf(i);
                    // mit post kannst du der View sagen, dass sie sich mit dem UI-Thread
                    // synchronisieren soll und das Runnable innerhalb des UI Threads ausführt
                    text.post(new Runnable() {
                      text.setText(zahl);                       
                    });

                }           
            }           
        };
        Thread t = new Thread(r);
        t.start();
    }
}
 
G

Gast2

Gast
alles was ich soeben geschrieben habe,
nehme ich zurück.
 
Zuletzt bearbeitet von einem Moderator:

schlingel

Gesperrter Benutzer
schlingel hat gesagt.:
Abgesehen davon, würdest du gleich die nächste Exception bekommen wenn du versuchst aus einem anderen Thread als dem UI-Thread auf die UI zuzugreifen.

=> Siehe Code den ich geposted habe, ist der so drinnen? Und holst du dir die Referenz noch im onCreate (findViewById) oder schon im Thread? Sollte nämlich im onCreate passieren.

Java:
text.post(new Runnable() {
                      text.setText(zahl);                       
                    });

Du bekommst nämlich keine NullPointerException sondern die angesprochene "nächste" Exception. CalledFromWrongThreadException, steht ja sogar im Logcat drinnen.
 
G

Gast2

Gast
=> Siehe Code den ich geposted habe, ist der so drinnen?

Du bekommst nämlich keine NullPointerException sondern die angesprochene "nächste" Exception. CalledFromWrongThreadException, steht ja sogar im Logcat drinnen.

Ja,
Entschuldigung bitte, hab ich nicht gleich korrekt übernommen,
irgendwann fiel mir ein, dass ich in Deinem Quelltext etwas von einer Übergabe gelesen habe. Dann sah ich's.

Nun bekomme ich Fehler im Quelltext angezeigt in Zeile text.setText(zahl); gleich zwei Meldungen

Multiple markers at this line
- Syntax error on token "zahl", VariableDeclaratorId expected after
this token
- Syntax error on token(s), misplaced construct(s)

...was ich nicht nachvollziehen kann,
da ja der TextView text oben deklariert wurde.

Muss ich das text.post ausserhalb von Runnable(){} irgendwie entgegennehmen?
 
Zuletzt bearbeitet von einem Moderator:

schlingel

Gesperrter Benutzer
Irgendwo passt was nicht mit deinen Sichtbarkeiten. Wo genau weiß ich nicht, aber bei mir funktionieren diese Varianten:

main.xml
[xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:eek:rientation="vertical" >

<TextView
android:id="@+id/lblSeconds"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="0" />

</LinearLayout>
[/xml]

TestprojectActivity.java
Java:
public class TestprojectActivity extends Activity {
	
	private TextView lblSeconds;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lblSeconds = (TextView)findViewById(R.id.lblSeconds);
//        Hier die etwas elegantere Variante mit dem AsyncTask
//        AsyncTask<Void, Integer, Void> t = new AsyncTask<Void, Integer, Void>() {
//        	@Override
//        	protected Void doInBackground(Void... params) {
//        		int i = 0;
//        		long timestamp = System.currentTimeMillis();
//        		
//        		while(i < 5) { /* busy waiting ist böse, aber soll auch nur ein beispiel sein */
//        			if(System.currentTimeMillis() - timestamp >= 1000) {
//        				i++;
//        				timestamp = System.currentTimeMillis();
//        				publishProgress(i);
//        			}
//        		}
//        		
//        		return null;
//        	}
//        	@Override
//        	protected void onProgressUpdate(Integer... values) {
//        		lblSeconds.setText(Integer.toString(values[0]));
//        	}
//        	
//        	@Override
//        	protected void onPostExecute(Void result) {
//        		Toast.makeText(TestprojectActivity.this, "Fertig!", Toast.LENGTH_SHORT).show();
//        	}
//        };
//        
//        t.execute();
        
//     Hier die Variante mit dem Thread.
        new Thread(new Runnable() {
                // das muss eine instanzvariable des Runnable sein, weil ich sonst in den anonymen Runnable
                // für die Updates nicht darauf zugreifen kann.
        	int i = 0;
        	
			public void run() {
				for(i = 0; i < 5; i++) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// immer brav post verwenden, sonst gibt's eine Exception
					lblSeconds.post(new Runnable() {
						public void run() {
							lblSeconds.setText(Integer.toString(i));
						}
					});
				}
				lblSeconds.post(new Runnable() {
					public void run() {
						Toast.makeText(TestprojectActivity.this, "Fertig!", Toast.LENGTH_SHORT).show();
					}
				});
			}
		}).start();
    }
}
 
G

Gast2

Gast
@Schlingel:

also die nicht auskommentierte Variante funktioniert.
Das macht mich heute (nachdem ich nicht so erfolgreich war) sehr glücklich! :D

Was nun genau mein Fehler war, weiß ich nicht.
Ich habe mein relativeLayout zum LinearLayout umgebaut und
Deinen Quelltext kopiert.

Im Quelltext fiel mir auf, dass eine Klammer jetzt anders steht.

lblSeconds.setText(Integer.toString(i));
}
});

Die fett markierte Klammer hatte ich zuvor an anderer Stelle.

Nun werde ich mir noch den auskommentierten Quelltext anschauen...

Vielen Dank! :toll:
 
G

Gast2

Gast
Toll, toll, toll,

auch die zweite AsyncTask-Variante läuft.
Du hast ja sogar meinen gestrigen Versuch mit dem timeStamp eingebaut. :)

Den habe ich aber (weil 'n bissl böse) mit Thread.sleep() ausgetauscht.

Für meine Arbeit brauche ich tatsächlich zwei Counter,
einen der anzählt ("Achtung gleich geht's los...!")
und einen zweiten, der eine Messung stoppen soll nach einer bestimmten Zeit
und der sollte wohl mgl. in einen zweiten Thread laufen.
Vielleicht bekomme ich das ja hin (nächste Woche;).

Danke und schönes Wochenende!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N XY-Plottet keine Daten obwohl Funktion ausgeführt wird Android & Cross-Platform Mobile Apps 4
N XY-Plot plottet keine Daten Android & Cross-Platform Mobile Apps 0
W Android Wieso kann ich keine ListView mehr zum Layout hinzufügen? Android & Cross-Platform Mobile Apps 1
W Android Kann keine ListView mehr in der MainActivtiy anzeigen, obwohl noch sehr viel Platz frei ist Android & Cross-Platform Mobile Apps 1
Dimax Android WebVieClient sendet keine Formulare Android & Cross-Platform Mobile Apps 1
J OnRatingBarChangeListener gibt keine Reaktion Android & Cross-Platform Mobile Apps 3
S Android kriege einfach keine HTTP Connection hin Android & Cross-Platform Mobile Apps 1
P Android JUnit Testprojekt warum keine Java Klassen Android & Cross-Platform Mobile Apps 1
A Wieso keine java - forum app Android & Cross-Platform Mobile Apps 4
S Android Eclipse erstellt keine main Activity Android & Cross-Platform Mobile Apps 4
K Android SQLite Query "WHERE _id in (X, Y, Z)" keine Daten Android & Cross-Platform Mobile Apps 6
P Android EditText zeigt keine Umlaute Android & Cross-Platform Mobile Apps 6
N "Schöne" Datatable in Android und setzen von Parametern von Textview im Code Android & Cross-Platform Mobile Apps 5
M Android Dynamische SchriftGröße einer TextView Android & Cross-Platform Mobile Apps 3
N Zugriff auf TextView in ListItem via ButtonClick Android & Cross-Platform Mobile Apps 4
D Android EditText und TextView haben unterschiedliche größen innerhalb einer TableRow Android & Cross-Platform Mobile Apps 18
G TextView ausgeben Android & Cross-Platform Mobile Apps 1
N Android bei textview.settext immer abbruch Android & Cross-Platform Mobile Apps 4
A Kann nicht in TextView einer anderen Klasse schreiben - wieso? Android & Cross-Platform Mobile Apps 9
J Android Multiline in TextView Android & Cross-Platform Mobile Apps 9
I Android Hintergrundfarbe von Textview (Shape) ändern Android & Cross-Platform Mobile Apps 19
N Textview macht immer nach einem Beistrich einen Abstand Android & Cross-Platform Mobile Apps 6

Ähnliche Java Themen

Neue Themen


Oben