java - Why goes a layout root through an observer? -


for hours have been working @ new android app, tangle myself @ strange exception. means exception clear, not understand content behind it.

i have activity named mainactivity :

public class mainactivity extends activity implements observer {

 private gamestate st = new gamestate();  private gameengine bc;  public relativelayout gamelayout;  @override protected void oncreate(bundle savedinstancestate) {     super.oncreate(savedinstancestate);     setcontentview(r.layout.activity_main);      st.addobserver(this);     gamelayout = (relativelayout) findviewbyid(r.id.glayout);     startgame();  }   @override public void update(observable observable, object data) {      int gamestate = ((gamestate) observable).getstate();      if(gamestate == 1){         continuegame();     }      if(gamestate == 2){         killgame();     } }  private void killgame(){      if(!bc.barthread.isinterrupted()){     bc.barthread.interrupt();     }     gamelayout.removeallviewsinlayout();      relativelayout.layoutparams params = new relativelayout.layoutparams(             layoutparams.wrap_content,             layoutparams.wrap_content             );     textview tv = new textview(this);      gamelayout.addview(tv, params);     tv.settext("game over"); } 

}

my simple gamestate class:

public class gamestate extends observable{  private int state = 0;  public gamestate() {  }  public void setstate(int var){      synchronized(this){         state = var;     }     setchanged();     notifyobservers();  }  public synchronized int getstate(){      return state;  } 

}

and gameengine (instantiated bc), long, post here, can try explain content in easy words.

the game engine features game elements buttons , progressbar , thread (barthread) fills bar continuously. if user successful, gameengine sets gamestate 1 , mainactivity killgame() method, works perfectly.

if user slow , progressbar full, barthread sets gamestate two. mainactivity killgame , throws

 android.view.viewrootimpl$calledfromwrongthreadexception: original thread created view hierarchy can touch views. 

but can not understand why thread has effect throught observer ?

i'm guessing barthread calls setstate(int var), right? if that's true, method called on thread not main thread. means setstate() calls (e.g. notifyobservers()) not called on main thread. i'm guessing notifyobservers() calls mainactivity.update(observable observable, object data), calls killgame(), changes view hierarchy (i.e. adding text view). means view hierarchy modified thread not main thread.

you're going need create handler in mainactivity. in killgame(), call handler.post(runnable runnable). this:

private handler handler;  @override public void oncreate(bundle savedinstancestate) {   handler = new handler(); }  private void killgame() {   if(!bc.barthread.isinterrupted()){     bc.barthread.interrupt();   }    handler.post(new runnable() {     @override     public void run() {       gamelayout.removeallviewsinlayout();        relativelayout.layoutparams params = new relativelayout.layoutparams(         layoutparams.wrap_content,         layoutparams.wrap_content       );       textview tv = new textview(mainactivity.this);        gamelayout.addview(tv, params);       tv.settext("game over");     }   }); } 

Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -