问题
So I was using the ActionBarSherlock and decided to switch to the new ActionBarCompat. With ABS, hiding the ActionBar was possible using the way described in this post: How to hide action bar before activity is created, and then show it again?
But, with the ActionBarCompat the app crashes on API14, because when you set android:windowActionBar as false the getSupportActionBar() method returns null, even if you have declared the getWindow().requestFeature(Window.FEATURE_ACTION_BAR); into the onCreate() method.
Funny thing is that if you call getActionBar() instead, you get the object and everything works fine.
So, is that a bug or am I missing something? Any ideas are welcome!
styles.xml file:
<style name="Theme.MyApp" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowActionBar">false</item>
    <item name="android:windowTitleSize">0dp</item>
</style>
MyActivity.java file:
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Get the action bar feature. This feature is disabled by default into the theme
    // for specific reasons.
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    ...
    // By default the action bar is hidden.
    getSupportActionBar().hide();
}
回答1:
I got stuck with the same problem and, it seems to me, found a reason of this strange behavior. I looked through source of support library and got this:
Appcompat checks a value of mHasActionBar variable before creating new action bar in ActionBarActivityDelegate
final ActionBar getSupportActionBar() {
    // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
    // could change after onCreate
    if (mHasActionBar || mOverlayActionBar) {
        if (mActionBar == null) {
            mActionBar = createSupportActionBar();
    ...
And we can change its value by calling supportRequestWindowFeature(int featureId) which is delegated by ActionBarActivity to a ActionBarActivityDelegate.
There are base delegate class ActionBarDelegateBase and its descendants ActionBarDelegateHC, ActionBarActivityDelegateICS, ActionBarActivityJB, one of which is chosen according to a version of running android. And method supportRequestWindowFeature is actually works fine almost in all of them, but it's overridden in ActionBarActivityDelegateICS like that
@Override
public boolean supportRequestWindowFeature(int featureId) {
    return mActivity.requestWindowFeature(featureId);
}
So it has no effect on the variable mHasActionBar, that's why getSupportActionBar() returns null.
We almost there. I came to two different solutions.
First way
- import source project of appcompat from git 
- change overridden method in - ActionBarActivityDelegateICS.javato something like this- @Override public boolean supportRequestWindowFeature(int featureId) { boolean result = mActivity.requestWindowFeature(featureId); if (result) { switch (featureId) { case WindowCompat.FEATURE_ACTION_BAR: mHasActionBar = true; case WindowCompat.FEATURE_ACTION_BAR_OVERLAY: mOverlayActionBar = true; } } return result; }
- place this line in activity's - onCreatemethod before- getSupportActionBar()- supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
Second way
- import project of appcompat from android SDK (which is with empty src directory) 
- add this method to your activity - private void requestFeature() { try { Field fieldImpl = ActionBarActivity.class.getDeclaredField("mImpl"); fieldImpl.setAccessible(true); Object impl = fieldImpl.get(this); Class<?> cls = Class.forName("android.support.v7.app.ActionBarActivityDelegate"); Field fieldHasActionBar = cls.getDeclaredField("mHasActionBar"); fieldHasActionBar.setAccessible(true); fieldHasActionBar.setBoolean(impl, true); } catch (NoSuchFieldException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (IllegalAccessException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (IllegalArgumentException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } catch (ClassNotFoundException e) { Log.e(LOG_TAG, e.getLocalizedMessage(), e); } }
- call - requestFeature()in- onCreatemethod of your activity like this- if (Build.VERSION.SDK_INT >= 11) { requestFeature(); } supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
I used the second way. That's all.
回答2:
I use this to hide ActionBar in AppCompat: style.xml
<style name="Theme.AppCompat.Light.NoActionBar" parent="@style/Theme.AppCompat.Light">
    <item name="android:windowNoTitle">true</item>
</style>
AndroidManifest.xml:
<activity
        android:name=".Splash"
        android:label="@string/title_activity_splash"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>
回答3:
I don`t know if I understood exactly your question, but here I go.
I think that you need to use both: getSupportActionBar() to old versions and getActionBar() to newest versions. It`s not a bug.
You need to verify the device version before use the methods.
I hope I was able to help.
回答4:
Does your activity extends ActionBarActivity? Probably it doesn't and that's why it's running with the getActionbar() method.
来源:https://stackoverflow.com/questions/18526144/actionbarcompat-hide-actionbar-before-activity-is-created-bug