JakeWharton / ActionBarSherlock

[DEPRECATED] Action bar implementation which uses the native action bar on Android 4.0+ and a custom implementation on pre-4.0 through a single API and theme.
http://actionbarsherlock.com
Apache License 2.0
7.1k stars 3.53k forks source link

Force close on GB base when slide right after press menu key #487

Open jjmartin88 opened 12 years ago

jjmartin88 commented 12 years ago

I am trying to integrate Sherlock action bar library into my application on GB based. I am using ViewPager together with Sherlock action bar to support sliding between tabs.

While I met force close by following bellow steps: 1) Press menu key 2) Slide the tab right after menu key pressed (you will notice action bar pop menu shows and then dismissed) 3) Try to slide again Result: force close occurs.

Logs:

05-21 17:02:27.736: E/AndroidRuntime(25836): FATAL EXCEPTION: main 05-21 17:02:27.736: E/AndroidRuntime(25836): java.lang.NullPointerException 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.widget.PopupWindow$1.onScrollChanged(PopupWindow.java:132) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.view.ViewTreeObserver.dispatchOnScrollChanged(ViewTreeObserver.java:607) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.view.ViewRoot.draw(ViewRoot.java:1369) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.view.ViewRoot.performTraversals(ViewRoot.java:1266) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.os.Handler.dispatchMessage(Handler.java:99) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.os.Looper.loop(Looper.java:130) 05-21 17:02:27.736: E/AndroidRuntime(25836): at android.app.ActivityThread.main(ActivityThread.java:3806) 05-21 17:02:27.736: E/AndroidRuntime(25836): at java.lang.reflect.Method.invokeNative(Native Method) 05-21 17:02:27.736: E/AndroidRuntime(25836): at java.lang.reflect.Method.invoke(Method.java:507) 05-21 17:02:27.736: E/AndroidRuntime(25836): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 05-21 17:02:27.736: E/AndroidRuntime(25836): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 05-21 17:02:27.736: E/AndroidRuntime(25836): at dalvik.system.NativeStart.main(Native Method)

Could your team take a look at this issue?

SimonVT commented 12 years ago

Doesn't seem related to ABS. You're sure this library is triggering the bug? Please provide a sample which exhibit this behavior.

androidmoney commented 12 years ago

I run into this problem and duplicated on my Nexus One Gingerbread.

It only happens only in Landscape mode, but this is a real problem when you have icons shown/hidden problematically.

Modified ActionModes.java is below.

Steps to reproduce:

1) Hit the Start button, this will display the action bar, with Button 2 and 3. 2) Hit the Cancel button, this will make Button 1 visible 3) Hit Button 3 by showing the overflow menu, this will make Button 1 disappear 4) Hit the Start button again, the app crashes.

In my "real app" I get the crash right after step 3 -- not exactly sure what's the difference.

public class ActionModes extends SherlockActivity { ActionMode mMode; boolean visible;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    setTheme(R.style.Theme_Sherlock); //Used for theme switching in samples
    super.onCreate(savedInstanceState);
    setContentView(R.layout.action_modes);

    ((Button)findViewById(R.id.start)).setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            ActionModes.this.visible = false;
            ActionModes.this.mMode = startActionMode(new AnActionModeOfEpicProportions());
        }
    });

    ((Button)findViewById(R.id.cancel)).setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            ActionModes.this.visible = true;
            ActionModes.this.mMode.invalidate();
        }
    });
}

private final class AnActionModeOfEpicProportions implements ActionMode.Callback
{
    public AnActionModeOfEpicProportions()
    {
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu)
    {
        menu.add("Button1") //$NON-NLS-1$
        .setIcon(R.drawable.ic_compose).setTitle("Long button 1").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        menu.add("Button2") //$NON-NLS-1$
        .setIcon(R.drawable.ic_search).setTitle("Long button 2").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        menu.add("Button3") //$NON-NLS-1$
        .setIcon(R.drawable.ic_refresh).setTitle("Long button 3").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu)
    {
        menu.getItem(0).setVisible(ActionModes.this.visible);

        return true;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item)
    {
        ActionModes.this.visible = false;
        mode.invalidate();

        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode)
    {
    }
}

}

androidmoney commented 12 years ago

This does NOT happen on native ICS, I just tested it.

androidmoney commented 12 years ago

I fixed this in my project by backporting the ICS PopupWindow class. It's a fairly trivial exercise (4 anims, 2 interpolators, 2 integers, couple of styles copied), but I don't really want to submit a diff as double checking my work would probably take as long as doing it in the first place. Unless you want me to....

Digipom commented 12 years ago

I'm getting market reports of this exception with Action Bar Sherlock v4.1.0 and the Android Support Library v4 revision 9. It seems to be affecting more than a few users out there.

Digipom commented 12 years ago

The problem appears to be this line for me:

View anchor = mAnchor.get();

on ICS it's this:

View anchor = mAnchor != null ? mAnchor.get() : null;

I'll try @androidmoney 's idea and see if I still get those crashes in the market.

Digipom commented 12 years ago

@androidmoney Could you share what you did too? I just want to compare to see if I did things the right way. Thanks!

Digipom commented 12 years ago

I still get some reports of this exception, but am not comfortable enough with porting over all of the styles etc... (i.e. not sure that what I'm doing would not be breaking something else). If anyone knows how to fix, would be greatly appreciated. :)

RawPhunky commented 12 years ago

I can reproduce same issue on old Samsung device running Android 2.2.1

I have ABS4 and ViewPager + ViewPagerIndicator. Theme.Sherlock.Light.DarkActionBar.ForceOverflow to force overflow menu Using Android Support Library, revision 10

A way to reproduce is to click overflow menu then try to swipe ViewPager, then click overflow menu item again. So basically swiping and clicking overflow menu item gets a crash after few swipes:

08-30 00:35:26.316: E/AndroidRuntime(28708): FATAL EXCEPTION: main 08-30 00:35:26.316: E/AndroidRuntime(28708): java.lang.NullPointerException 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.widget.PopupWindow$1.onScrollChanged(PopupWindow.java:124) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.view.ViewTreeObserver.dispatchOnScrollChanged(ViewTreeObserver.java:607) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.view.ViewRoot.draw(ViewRoot.java:1253) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.view.ViewRoot.performTraversals(ViewRoot.java:1163) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.view.ViewRoot.handleMessage(ViewRoot.java:1727) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.os.Handler.dispatchMessage(Handler.java:99) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.os.Looper.loop(Looper.java:123) 08-30 00:35:26.316: E/AndroidRuntime(28708): at android.app.ActivityThread.main(ActivityThread.java:4633) 08-30 00:35:26.316: E/AndroidRuntime(28708): at java.lang.reflect.Method.invokeNative(Native Method) 08-30 00:35:26.316: E/AndroidRuntime(28708): at java.lang.reflect.Method.invoke(Method.java:521) 08-30 00:35:26.316: E/AndroidRuntime(28708): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 08-30 00:35:26.316: E/AndroidRuntime(28708): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 08-30 00:35:26.316: E/AndroidRuntime(28708): at dalvik.system.NativeStart.main(Native Method)

annie-l commented 12 years ago

Yeah, apparently this was fixed in Honeycomb. Would be nice if this was fixed in ABS so pre-Honeycomb wouldn't experience this crash.

https://android.googlesource.com/platform/frameworks/base/+/749b0eb2c9a52bb188fd8900859b3725889e0ec0%5E!/

edisonw commented 11 years ago

Not sure where to hook the code. But you can certainly fix it via reflection when possible.

if(Build.VERSION.SDK_INT<Build.VERSION_CODES.ICE_CREAM_SANDWICH){ try { final Field fAnchor = PopupWindow.class.getDeclaredField("mAnchor"); fAnchor.setAccessible(true); Field listener = PopupWindow.class.getDeclaredField("mOnScrollChangedListener"); listener.setAccessible(true); final ViewTreeObserver.OnScrollChangedListener originalListener = (ViewTreeObserver.OnScrollChangedListener) listener.get(window); ViewTreeObserver.OnScrollChangedListener newListener= new ViewTreeObserver.OnScrollChangedListener() { public void onScrollChanged() { try { View mAnchor = (View) fAnchor.get(window); if(mAnchor==null){ return; }else{ originalListener.onScrollChanged(); } } catch (Exception e) { e.printStackTrace(); } } }; listener.set(window,newListener); } catch (Exception e) { e.printStackTrace();
} }