android - PopupWindow.showAtLocation() causes WindowManager$BadTokenException when using onSaveInstanceState() to handle device rotation -


i have been working on straight-forward file manager application. devices have been using testing lg nexus 4 (v4.3) , xperia x10i (v2.3.7). performance on x10i, although bit sluggish, has been problem-free.

on rotation:

there several popupwindows keep track of. use flags determine popupwindow on screen (presently, @ 1 popupwindow on screen @ given time). in onsaveinstancestate(bundle), save these flags using bundle. in oncreate(bundle), retrieve these flags , use them in onpostexecute() of asynctask(called in onresume() , used populating listview data).

the problem:

if popupwindow showing when device rotated, activity destroyed, recreated, , popupwindow displayed again. works on both devices. but, today, rotated x10i 90 degrees 270 degrees while search popup showing. app crashed because of following exception:

08-08 01:55:51.961: e/androidruntime(32373): fatal exception: main 08-08 01:55:51.961: e/androidruntime(32373): android.view.windowmanager$badtokenexception: unable add window -- token null not valid; activity running? 08-08 01:55:51.961: e/androidruntime(32373):    @ android.view.viewroot.setview(viewroot.java:544) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.view.windowmanagerimpl.addview(windowmanagerimpl.java:177) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.view.windowmanagerimpl.addview(windowmanagerimpl.java:91) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.view.window$localwindowmanager.addview(window.java:424) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.widget.popupwindow.invokepopup(popupwindow.java:907) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.widget.popupwindow.showatlocation(popupwindow.java:767) 08-08 01:55:51.961: e/androidruntime(32373):    @ com.apprehension.phylerfilemanager.phyler.showpopupsearch(phyler.java:2852) 08-08 01:55:51.961: e/androidruntime(32373):    @ com.apprehension.phylerfilemanager.phyler$displayfilestask.onpostexecute(phyler.java:3453) 08-08 01:55:51.961: e/androidruntime(32373):    @ com.apprehension.phylerfilemanager.phyler$displayfilestask.onpostexecute(phyler.java:1) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.os.asynctask.finish(asynctask.java:417) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.os.asynctask.access$300(asynctask.java:127) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.os.asynctask$internalhandler.handlemessage(asynctask.java:429) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.os.handler.dispatchmessage(handler.java:99) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.os.looper.loop(looper.java:123) 08-08 01:55:51.961: e/androidruntime(32373):    @ android.app.activitythread.main(activitythread.java:3701) 08-08 01:55:51.961: e/androidruntime(32373):    @ java.lang.reflect.method.invokenative(native method) 08-08 01:55:51.961: e/androidruntime(32373):    @ java.lang.reflect.method.invoke(method.java:507) 08-08 01:55:51.961: e/androidruntime(32373):    @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:862) 08-08 01:55:51.961: e/androidruntime(32373):    @ com.android.internal.os.zygoteinit.main(zygoteinit.java:620) 08-08 01:55:51.961: e/androidruntime(32373):    @ dalvik.system.nativestart.main(native method) 

line 2852:

popupwindowsearch.showatlocation(popupviewsearch, gravity.center, 0, 0);     

if rotate , pause on every 90 degrees, problem not there. crash happens when device undergoes 180 degree rotation without pause.

saving flags:

@override protected void onsaveinstancestate(bundle outstate) {     super.onsaveinstancestate(outstate);                  if (searchpopup) {         outstate.putboolean("searchpopup", searchpopup);         outstate.putstring("searchkeyword", searchkeyword);         outstate.putint("searchtype", searchtype);               }      if (....) {         ........         ........     } } 

retrieving flags in oncreate(bundle):

if (savedinstancestate != null) {      rotated = true;      if (savedinstancestate.containskey("searchpopup")) {         searchpopup = true;         searchkeyword = savedinstancestate.getstring("searchkeyword");         searchtype = savedinstancestate.getint("searchtype");     }      ....     .... } 

an asynctask executed onresume(). in onpostexecute() of asynctask:

if (rotated) {     rotated = false;     if (searchpopup) {         showpopupsearch(searchtype, searchkeyword);     // line 3453                             }     ....     .... } else {     searchpopup = false;     ....     .... } 

the exception not thrown while testing on nexus 4. have tried posting runnable mcontentview's (the activity's main view) message queue. problem persists.

i think there problem in way handling screen rotation. in apps have used, screen rotation , layout changes happen smoothly. in app's case, can literally tell popupwindow being dismissed , recreated. apps handle screen rotation using android:configchanges="keyboardhidden|orientation|screensize"? have read approach isn't correct.

what happening x10i doing 2 activity instantiations. causing 2 asynctasks run. first 1 end having reference instance of activity that, in eyes of framework , window manager, no longer exists (or should exist), causing null token , resulting exception.

in activity#onstop should set asynctask#cancel , in asynctask#onpostexecute check if canceled , if don't create popup window.


actual solution:

create flag in activity set false in oncreate(). in onstop() set true , in onpostexecute check if set , if not show popup window.


Comments

Popular posts from this blog

image - ClassNotFoundException when add a prebuilt apk into system.img in android -

I need to import mysql 5.1 to 5.5? -

Java, Hibernate, MySQL - store UTC date-time -