TextView aktualisiert sich nicht

  • 10 Antworten
  • Letztes Antwortdatum
T

Tobls22

Neues Mitglied
0
Hi bin gerade dabei eine App zu programmieren bei der sich ein Wert pro sekunde um 1 erhöht und man den Wert auf einem Textview sieht.
Nun habe ich aber das Problem, dass sich der Wert im Log höchzählt aber sich der Textview nur aktualisiert, wenn ich auf einen Knopf drücke oder eine andere Aktion mache.

Hier ist mein Code:
public class MainActivity extends ActionBarActivity {

public int variable = 1;
public TextView tv1;


public int Wert = 0;
public int Erhöhung = 1;



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

int variable = 1;
TextView tv1;


int Wert = 0;
int Erhöhung = 1;

tv1 = (TextView) findViewById(R.id.tv1);
tv1.setText(Integer.toString(variable));

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

Runnable r = new Runnable() {
@Override
public void run() {
while(true) {
try {

variable = variable + Erhöhung;
Thread.sleep(1000);
Log.d("variable: ",Integer.toString(variable));
tv1.setText(Integer.toString(variable));
}
catch (Exception e) {
e.printStackTrace();
Log.d("variable: ",Integer.toString(variable));
tv1.setText(Integer.toString(variable));

}
}

}
};



Und hier der Error den ich im Log bekomme:

02-21 11:14:45.837 2187-2205/de.tobls.test D/variable: 16
02-21 11:14:45.837 2187-2205/de.tobls.test W/System.err android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-21 11:14:45.837 2187-2205/de.tobls.test W/System.err at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:902)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.view.ViewGroup.invalidateChild(ViewGroup.java:4637)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.view.View.invalidateInternal(View.java:11690)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.view.View.invalidate(View.java:11654)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.view.View.invalidate(View.java:11638)
02-21 11:14:45.838 2187-2205/de.tobls.test W/System.err at android.widget.TextView.checkForRelayout(TextView.java:6842)
02-21 11:14:45.839 2187-2205/de.tobls.test W/System.err at android.widget.TextView.setText(TextView.java:4047)
02-21 11:14:45.839 2187-2205/de.tobls.test W/System.err at android.widget.TextView.setText(TextView.java:3905)
02-21 11:14:45.839 2187-2205/de.tobls.test W/System.err at android.widget.TextView.setText(TextView.java:3880)
02-21 11:14:45.839 2187-2205/de.tobls.test W/System.err at de.tobls.test.MainActivity$1.run(MainActivity.java:51)
02-21 11:14:45.839 2187-2205/de.tobls.test W/System.err at java.lang.Thread.run(Thread.java:818)
02-21 11:14:45.840 2187-2205/de.tobls.test D/variable: 16


hoffe mir kann da wer helfen
 
ähhhm ja keine Ahnung warum du in onCreate nochmals 4 variablen erstellst und nichts mit denen anfängst aber ok
2. benutz am besten den knopf für die Code formatierung hier im forum beim erstellen deines textes
und 3. das ist nun mal die Eigenschaft von solchen standard views dass die sich irgendwann mal selbst neu zeichnen(hat mit performance zu tun)
du könntest deren onDraw() Methode direkt rufen aber das stellt nciht sicher dass die sich sofort neu zeichnen und wird von manchen nciht empfolen

aber wenn du willst versuch tv1.onDraw() nach setText einzufügen und guck mal ob es kalppt

Der ursprüngliche Beitrag von 15:57 Uhr wurde um 16:01 Uhr ergänzt:

ach ja sorry jetzt weiß ich wieder wieso man das nciht machen sollte...du hast den canvas nciht zur hand

egal vergiss was ich obne gesagt habe und rufe stattdessen : tv1.postInvalidate() auf das sollte klappen
 
ehrlich gesagt wundert es mich, dass sich der TextView überhaupt aktualisiert, normalerweise müsste es eine CalledFromWrongThreadException erwartet.

mit runOnUiThread kannst du den setText im UI Thread aufrufen.
 
du kannst das natürlich umgehen und eine thread klasse erstellen die ein Textview objekt als member besitzt und dessen referenz auf das Textview vom UI thread legst
 
Ich weiß nicht ob man so ohne Weiteres an die Referenz der UI rankommt.

so wie markus.tullius es gepostet hat, sollte es auf jeden Fall gehen
 
  • Danke
Reaktionen: markus.tullius
Jaiel schrieb:
du kannst das natürlich umgehen und eine thread klasse erstellen die ein Textview objekt als member besitzt und dessen referenz auf das Textview vom UI thread legst

Zwei Threads machen es nicht besser.

Only the original thread that created a view hierarchy can touch its views.

Das heißt, du muss es im UiThread machen. Die andere Lösung wäre möglicherweise ein Handler.
 
Eine View:
PHP:
GameActivity gAct;


public GameView(Context context,GameActivity gAct) 
	{
		super(context);
		this.context=context;
		
		this.gAct=gAct;
                if(this.gAct!=null)
                    this.gAct.setSth();
	}

Die Activity
PHP:
public class GameActivity extends Activity{
	
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(new GameView(this,this));
	    
	}
	
	public void setSth()
	{
		finish();
	}
	

}


klappt phne Probleme ich kann über die View operationen im UI Thread aufrufen.

Die View kann natürlich auch ein Thread sein

Der ursprüngliche Beitrag von 20:52 Uhr wurde um 20:55 Uhr ergänzt:

also man kann sogar die Instanz der Activity weiterreichen und damit viele sachen ausserhlab des UI Threads anstellen wie z.B. eine neue Activity starten oder so.
Vorsichtig sollte man sein wenn die app gekillt wird :man sollte die Referenz dann natürlich neu aktualisieren um kein nullpointerex zu kriegen
 
Ob TextView tv1 jetzt eine locale Variable ist oder ein Attribut der inneren Klasse ist oder ein Attribut der Activity Klasse ist, wird nichts daran ändern, dass die CalledFromWrongThreadException fliegt, wenn sie von einem anderem Thread verändert wird.
 
jo er könnte eine methode setTextView im UI Thread anlegen und diese von außerhalb aufrufen :)(-->siehe setSth() bei mir im Beispiel)
 
@Jail du denkst zu sehr um die Ecke.

Halte es einfach. Und bau kein Spaghetticode. Gerade bei Threads sollte man vorsichtig agieren. Man kann dort echt Chaos anrichten.

Bei Threads weiß man nicht, wann sie was zur Laufzeit machen. Gib den GC einfach eine Chance, die Referenzen aufzuräumen.

Deshalb gibt es ja auch den AsynTask und die Möglichkeit mit runOnUiThread () auf den UIThread zu zugreifen. Gerade weil Threads bei Java ein Thema für sich sind.
 
Zurück
Oben Unten