Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crash after adding item to action bar's options menu from Fragment followed by orientation change

I'm using ActionBarSherlock and ViewPagerIndicator to display Fragments as tabs. One of those Fragments adds items to ActionBar:

private String[] mapNames;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    // init an String array `mapNames` which is used when populating submenu
    // ...
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    inflater.inflate(R.menu.fragment_maps, menu);

    SubMenu mapNamesMenu = menu.findItem(R.id.map_names).getSubMenu();
    mapNamesMenu.clear();
    for (int i=0; i<mapNames.length; i++) {
        mapNamesMenu.add(1, i, Menu.NONE, mapNames[i]);
    }

    super.onCreateOptionsMenu(menu, inflater);
}

and in res/menu/fragment_maps.xml I have

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/map_names"
        android:title="Maps"
        android:icon="@drawable/maps_32"
        android:showAsAction="always|withText">
        <menu>
            <item android:id="@+id/placeholder_maps" />
        </menu>
    </item>
</menu>

Everything is working fine until I rotate my phone. After orientation change this menu becomes inaccessible (nothing happens when icon is clicked). Then if I rotate my phone again I get this error:

FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:532)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:912)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:824)
at com.actionbarsherlock.internal.widget.IcsListPopupWindow.show(IcsListPopupWindow.java:226)
at com.actionbarsherlock.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:129)
at com.actionbarsherlock.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:102)
at com.actionbarsherlock.internal.view.menu.ActionMenuPresenter.onSubMenuSelected(ActionMenuPresenter.java:273)
at com.actionbarsherlock.internal.view.menu.MenuBuilder.dispatchSubMenuSelected(MenuBuilder.java:263)
at com.actionbarsherlock.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:892)
at com.actionbarsherlock.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:510)
at com.actionbarsherlock.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:145)
at android.view.View.performClick(View.java:2494)
at android.view.View$PerformClick.run(View.java:9122)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

Any ideas how to solve it? I'm using Android 2.3.6

Edit: see test repository

like image 798
Kuitsi Avatar asked Nov 20 '12 12:11

Kuitsi


1 Answers

I think , This is a Context problem. That's why BadTokenException is occurring.

There are many possibilities behind this exception:

1) May be you are using "this" as a context-reference at some place where it actually needs YourActivity.this or the parent activity's context.

OR

2) From the log-cat i am guessing, you are trying to display a Pop-up window.

The problem may be, you are displaying Pop-up window too early (i.e. before the Activity life cycle completes.). So wait till the activity life cycle completes.

To defer showing the popup, you can refer this link.

In-short this problem is due to the below use-case:

An activity's reference is passed to the some component (i.e. like Toast, alert dialog, pop-up etc), and activity destroyed but that component is still alive or trying to use destroyed activity's context.

So make sure that there isn't any situation like this.

Hope this will you give you some hint about solving the problem.

like image 133
Moin Ahmed Avatar answered Sep 28 '22 07:09

Moin Ahmed