なるようになるかも

力は多くの場合、その人の思いを超えない。

AppCompatDelegateの話。

Toolbarは正直ないわーって感じなんですけど、皆様は適合されたんでしょうか。

DroidKaigiなるイベントがあったらしく、Toolbarが受け入れられるのかディスられるのかが気になっていたのですけど、「BaseActivityの是非」が一番のトピックだったっぽい?個人的には、IntentなどのAndroidのルールを隠蔽するために、

nextScreen(ActivityFactory.createFromId(GAMEN_ID_HOGE));

みたいなオレオレ画面遷移メソッドを実装しているBaseActivityは爆破したくなりますが、それ以外で不満を持ったことはない感じです。

さて、AppCompatDelegateの話です。ActionBarActivityは死んでAppCompatDelegateの時代が来ました。それをざっくり説明すると以下の通りです。

今までのサポートライブラリ

f:id:quesera2:20150504181917p:plain

FragmentActionBarの概念が導入されたのはAndroid3.0。このうちFragmentAPIレベル4まで、ActionBarAPIレベル7までバックポートされています。

Fragmentのバックポートの責務はFragmentActivityに、ActionBarのバックポートの責務はActionBarActivityにあったため、上のような継承構造となっていました。

どう変わったか

f:id:quesera2:20150504191246p:plain

AppComatDelegateActionBarのバックポートや、マテリアルデザインのための諸々の責務を全て委譲するように変わりました。

実際のところ、少し前からActionBarActivityDelegateという名前で、ほぼ現在と近い実装になっていました。22.1というマイナーアップデートでお披露目となっているのもそのためだと思っています。

AppCompatActivityは単なるガワです。継承しなくても互換性のあるアプリを作ることができます。

これまでの継承構造では、PreferencesActivityが死にクラスになっていたとしばしば批判されていました。AppCompatPreferenceActivityというサンプルを見るのが分かりやすいのですが、この変更によって、どのような継承構造のActivityであっても、AppComatDelegateに処理を委譲することで互換性を維持できるのです!!

というのは嘘です。

確かに公式ブログにも、

However, this wasn’t just a rename. In fact, the internal logic of AppCompat is now available via AppCompatDelegate - a class you can include in any Activity, hook up the appropriate lifecycle methods, and get the same consistent theming, color tinting, and more without requiring you to use AppCompatActivity (although that remains the easiest way to get started).


私訳:しかしながら、この変更は単なる改名ではありません。AppCompatの内部ロジックは全てAppCompatDelegateにより今すぐ利用可能です。このクラスはAppCompatActivityを必要とせず、あらゆるActivityに取り込むことができ、ライフサイクルメソッドと適切に連携することで、一貫性のあるテーマ、色の変異(color tinting)などを実現できます。(それを開始する最も簡単な方法として、AppCompatActivityも残されています)

というようなことが書いてあります。

しかし、AppCompatActivityFragmentActivityを継承していることを忘れないで下さい。

FragmentActivityが扱っているのはv4のFragment(偽)です。普通のActivityが扱うFragment(真) とは別物です。

AppComatDelegateが解決する問題はマテリアルデザインとActionBar(と便宜的に呼ばれ続けているToolbar)の領域だけなのです。そのため、独自のActivityに組み込んでもいいケースは、Fragmentを使う機会が全くないか、もしくはandroid.support.v4.app.Fragmentandroid.app.Fragmentが混在しても支障がない場合に限られるということです。同様のことはLoaderにも言えます。

AppCompatActivityは必ず継承した方が無難だと思います。

また、AppCompatDelegateが扱うToolbarはv7のToolbar(偽)であり、普通のActivityが扱うToolbar(真)とは別物なのも微妙なトラップなのでご注意下さい。