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
Post a Comment