android - called from wrong thread + inner classes .. strange behaviour -


i'd explain me why fails...

my activity has inner class, apphelper, exports function setthrobber. simplicity have omitted init code, etc..

this function setthrobber meant called outside of ui thread, during network loads, report progress... then, classes use inner class apphelper method setthrobber so, network-loader thread.

to surprise, first approach fails (see error @ end) , second succeeds. why isn't first 1 executed in ui thread , second 1 is??? more strange is, in error stack trace looks called ui thread, though android throws called wrong thread exception. why not both code chunks equivalent thread point of view?

pd- tried handler.post() same result! pd2- apphelper class instantiated inside oncreate

thanks in advance !!

public class myapplication extends activity {      private progressdialog progressdialog;      void setthrobber_internal (string message) {          progressdialog.setmessage(message);     }      public class apphelper {          public setthrobber(final string msg) {              myapplication.this.runonuithread(new runnable() {                  @override                   public void run() {                      setthrobber_internal(msg);                      // throws calledfromwrongthread (!!)                  }              });          }     } } 

versus

public class myapplication extends activity {      private progressdialog progressdialog;      private void setthrobber_internal(final string msg) {           // runuithread here instead of in inner class wrapper           runonuithread(new runnable() {              @override               public void run() {                  progressdialog.setmessage(msg);              }          });      }       public class apphelper {          public void setthrobber(final string msg) {              setthrobber_internal(msg); // works ok         }     } } 

the stack trace of first situation:

e/androidruntime(17677): fatal exception: main e/androidruntime(17677): android.view.viewrootimpl$calledfromwrongthreadexception: original thread created view hierarchy can touch views. e/androidruntime(17677):    @ android.view.viewrootimpl.checkthread(viewrootimpl.java:4039) e/androidruntime(17677):    @ android.view.viewrootimpl.invalidatechild(viewrootimpl.java:722) e/androidruntime(17677):    @ android.view.viewrootimpl.invalidatechildinparent(viewrootimpl.java:771) e/androidruntime(17677):    @ android.view.viewgroup.invalidatechild(viewgroup.java:4005) e/androidruntime(17677):    @ android.view.view.invalidate(view.java:8576) e/androidruntime(17677):    @ android.view.view.invalidate(view.java:8527) e/androidruntime(17677):    @ android.widget.textview.checkforrelayout(textview.java:6760) e/androidruntime(17677):    @ android.widget.textview.settext(textview.java:3306) e/androidruntime(17677):    @ android.widget.textview.settext(textview.java:3162) e/androidruntime(17677):    @ android.widget.textview.settext(textview.java:3137) e/androidruntime(17677):    @ com.android.internal.app.alertcontroller.setmessage(alertcontroller.java:261) e/androidruntime(17677):    @ android.app.alertdialog.setmessage(alertdialog.java:185) e/androidruntime(17677):    @ android.app.progressdialog.setmessage(progressdialog.java:314) ---------------------------------- e/androidruntime(17677):    @ com.regaliz.libneo.nativestory.setthrobber_internal(nativestory.java:269) e/androidruntime(17677):    @ com.regaliz.libneo.nativestory$apphelper$8.run(nativestory.java:865) ---------------------------------- e/androidruntime(17677):    @ android.os.handler.handlecallback(handler.java:605) e/androidruntime(17677):    @ android.os.handler.dispatchmessage(handler.java:92) e/androidruntime(17677):    @ android.os.looper.loop(looper.java:137) 

request additional code:

  • the apphelper class instantiated inside main activity, , passed other child classes in activity, keep weakreference (checked not problem)

  • the classes use apphelper fails do:

public void story_loadfonts(string jsonfonts) {      final apphelper apphelper=mweakapphelper.get(); // apphelper stored in weak ref      try {         .         .         .         new thread(new runnable() {             @override             public void run() {                 try {                     (int i=0; i<numfonts; i++) {                         load_font_from_network(i);                         apphelper.setthrobber("loading font "+i+"/"+numfonts);                     }                 } catch (jsonexception e) {                     e.printstacktrace();                 }             }         }).start();     } catch (exception e) {         return;     } } 

looking @ ticked answer android: accessing ui element timer thread, wonder if issue runonuithread call created.

according android developer pages, runonuithread:

runs specified action on ui thread. if current thread ui thread, action executed immediately. if current thread not ui thread, action posted event queue of ui thread.

note android java runonuithread() calling post on activity's handler same calling runonuithread.

so, question how handler associate first case different handler in second case.

in second case, suspect guaranteed post handler associated main activity.

in second case, is, infer, handler associated thread created apphelper, should same, say.

edit: based on further interaction question author, key follows:

it seems onpause stops activities ui thread dead, , onresume creates fresh one. handler can access renewed process.

the (final, weak) appholder instantiation associated old ui thread handler, , if runonuithread executed inside it, refers old holder (via runonuithread). is situation first case.

however, in second case, call runonuithread no longer executed in code (called being pre-onpause), rather in method inside main activity have updated handler runonuithread calls.

in short: make sure calls runonuithread (and indeed handler.post()) done in way guarantees using recent live version of activity (and it's ui thread), , aren't linking previous versions.


Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -