ActionBar を持たないテーマを設定した Activity でやっておかないと悲しいクラッシュに遭遇した話

テーマとして、`android:windowNoTitle="true"`を設定することで、ActionBar を表示させないようにすることができます。

こうすると、ActionBar を持たない Activity が出来上がるため、`Activity#getActionBar()`や`Activity#getSupportActionBar()`は`null`を返すようになります。

この場合、以下の点について気をつけていないと、見に覚えのないクラッシュログに苛まれることになります。

## メニューキーを無効化する

メニューキーは、すなわち ActionItem の OverFlow の中身を呼び出す機能として使われます。

つまり、ActionBar の機能を使おうとします。

しかし、`android:windowNoTitle="true"`なテーマの Activity では、ActionBar そのものが生成されないので、メニューキーのハンドリングをした時に NullPointerException となってしまいます。

例えば、以下の様なクラッシュレポートが来た場合、まさにこのような状況にあると言えます。

```
java.lang.NullPointerException
	at android.support.v7.a.r.b(ActionBarImplICS.java:219)
	at android.support.v7.a.r.(ActionBarImplICS.java:52)
	at android.support.v7.a.r.(ActionBarImplICS.java:41)
	at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:47)
	at android.support.v7.a.g.b(ActionBarActivityDelegate.java:81)
	at android.support.v7.a.f.getMenuInflater(ActionBarActivity.java:71)
	at android.app.Activity.onCreatePanelMenu(Activity.java:2445)
	at android.support.v4.app.q.onCreatePanelMenu(FragmentActivity.java:224)
	at android.support.v7.a.f.a(ActionBarActivity.java:232)
	at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:147)
	at android.support.v7.a.f.onCreatePanelMenu(ActionBarActivity.java:199)
	at android.support.v7.a.m.onCreatePanelMenu(ActionBarActivityDelegateICS.java:285)
	at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:388)
	at com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel(PhoneWindow.java:779)
	at com.android.internal.policy.impl.PhoneWindow.onKeyDown(PhoneWindow.java:1444)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1833)
	at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3466)
	at android.view.ViewRootImpl.handleFinishedEvent(ViewRootImpl.java:3439)
	at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2577)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:4475)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
	at dalvik.system.NativeStart.main(Native Method)
```

この回避策として、メニューキーを無効化する手段があります。

```java

    @Override // avoid inflating menu without action bar
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ( keyCode == KeyEvent.KEYCODE_MENU ) {
            // do nothing
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
```

## WebView の LongClick を無効化する

WebView は、デフォルトで長押しのイベントをハンドリングし、テキストの選択状態を取り扱うことが出来るようになります。
すると、テキストが選択状態になった時、Contextual ActionBar が有効になります。

つまり、ActionBar の機能を使おうとします。

しかし、前述のとおり ActionBar のインスタンスは無いので、またしても NullPointerException となります。

例えば、以下の様なクラッシュレポートが来た場合、まさにこのような状況にあると言えます。

```
java.lang.NullPointerException
	at android.support.v7.a.r.b(ActionBarImplICS.java:219)
	at android.support.v7.a.r.(ActionBarImplICS.java:52)
	at android.support.v7.a.r.(ActionBarImplICS.java:41)
	at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:47)
	at android.support.v7.a.g.b(ActionBarActivityDelegate.java:81)
	at android.support.v7.a.g.k(ActionBarActivityDelegate.java:205)
	at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:196)
	at android.support.v7.a.m.onActionModeStarted(ActionBarActivityDelegateICS.java:351)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionMode(PhoneWindow.java:2255)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionModeForChild(PhoneWindow.java:2178)
	at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
	at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
	at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
	at android.view.View.startActionMode(View.java:3607)
	at android.webkit.WebView.setUpSelect(WebView.java:6103)
	at android.webkit.WebView.selectText(WebView.java:4873)
	at android.webkit.WebView.selectText(WebView.java:4866)
	at android.webkit.WebView.performLongClick(WebView.java:4851)
	at android.webkit.WebView$PrivateHandler.handleMessage(WebView.java:9422)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:4475)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
	at dalvik.system.NativeStart.main(Native Method)
```

WebView の長押しを無効化するには、以下のようにします。


```java
WebView webview = ...'
webview.setLongClickable(false);
webview.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
        return true; // successfully handled.
    }
});
```