AlertDialog#show()とActivity#showDialog()

Androidでダイアログを表示するときに利用するのが、AlertDialogクラスです。
Webでダイアログの表示について書かれた記事の多くは、AlertDialog#show()を用いています。

一方、本家のAndroid Developersでは、Activity#showDialog()を用いたサンプルコードが記載されています。
Dialogs | Android Developers
6.4 ダイアログの作成 - ソフトウェア技術ドキュメントを勝手に翻訳

Activity#showDialog()で表示するダイアログは、Activity#onCreateDialog()にて別途生成を行います。

show()とshowDialog()の違い

両者の違いは、「DialogがActivityに管理されるかどうか」です。show()だけでは、ダイアログはActivityに管理されません。

Activityにダイアログを管理させておくと、Activity自身の状態変化に応じて、適宜ダイアログを出し入れしてくれます。

管理されないダイアログの問題

よく遭遇するケースは、画面の回転時です。
Activityは回転時にonDestroyされますが、このときshowされっぱなしのDialogはリークを引き起こします。
このとき、logcatには下記のエラーメッセージが表示されます。

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity xxx has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity xxx has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.ViewRoot.(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Dialog.show(Dialog.java:239)

強制終了時のようなスタックトレースですが、Exceptionが発生しているわけではありません。(Exception発生ならアプリが落ちますが、この場合は落ちません)
Androidフレームワークは、Activityを破棄する際にリークの有無を検査します。
リークを検出すると、あらかじめ保持していたwindowのトレース情報を表示します。

AndroidManifest.xmlにて、Activityが回転時に破棄されないようにすれば回転時の問題は回避できます*1が、それ以外でonDestroyが呼ばれるケースには対処できません。
onDestroy内でdismissするという対処もありますが、Activityに管理させておけばそのような記述は必要ありません。さらに、回転時も勝手にダイアログの状態を復元してくれます。
これは、savedInstanceStateとrestoreInstanceState内で、管理されたDialogの保存/復元処理が行われるからです。

結論

ダイアログは特別な理由がなければ、onCreateDialogにより管理させましょう。

*1:android:configChangesに"orientation|keyboardHidden|screenSize"を指定