2011年4月6日水曜日

Fragmentとandroid-support-v4.jar


"SDK"/extra/android/compatibilityにある
FragmentManager.javaを読んだけど
新しいUI部品というよりはユーティリティーの追加のように感じる。
本来のFragmentの実装ではなく
Fragmentとほぼ同じ機能を有した外部ライブラリとして
FragmentActivityとかを実装しているわけだから、それは仕方のないことかも。
サンプルとしては、
FramgnetStackSupport.javaを参考にすればいい。
基本的には、FragmentXXXSupport.javaが外部ライブラリを利用したサンプルになる。

だが、そもそもFragmentを利用するメリットはどこにあるのだろうか?
画面遷移が画面全体の一部の差し替えになることで
かっこいいUIをつくることが出来る。
これは、Viewのadd removeでも出来たことだ。
でも、なんであえてこんなモノがあるのかの理由は
http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html
に書いてある。
XMLを変えて、Activityを一部増やすことで
tablet向けにつくっていたActivityをソースコードをまるまる流用して
二つのActivityに分けることが出来ると言っているわけだ。

ただ、ここで気になってくるのがライフサイクルだ。
compatibilityの外部ライブラリを利用した場合の
FragmentとActivityのライフサイクルと
本来のFragmentとActivityのライフサイクルが一緒なのだろうか?
結論を書くと全然違った!!

ApiDemosにあるFragmentHideShow.javaをほとんどパクって
compatibilityの外部ライブラリを利用して作成したプロジェクトと
3.0の本物のFragmentを利用して作成したプロジェクトを作った。
長いからサンプルコードは貼り付けないが、
FragmentActivityはActivity
FirstFragmentはFragment
SecondFragmentはFragment
で、その各コールバックにEnter/Exitのログを仕込んだ。
Logcatで見えやすいのでログレベルをあえて分けた。

2.3.3 & android-support-v4.jarで作ったFragmentのサンプル


3.0で作ったFragmentのサンプル



結果としては、
2.3.3 & android-support-v4.jarのログ
----------------------------------------
Enter FragmentActivity#onCreate
Enter SecondFragment#onAttach
Exit SecondFragment#onAttach
Enter SecondFragment#onCreate
Exit SecondFragment#onCreate
Enter SecondFragment#onCreateView
Exit SecondFragment#onCreateView
Enter FirstFragment#newInstance
Exit FirstFragment#newInstance
Exit FragmentActivity#onCreate
Enter FragmentActivity#onStart
Enter FirstFragment#onAttach
Exit FirstFragment#onAttach
Enter FirstFragment#onCreate
Exit FirstFragment#onCreate
Enter SecondFragment#onActivityCreated
Exit SecondFragment#onActivityCreated
Enter SecondFragment#onStart
Exit SecondFragment#onStart
Enter FirstFragment#onCreateView
Exit FirstFragment#onCreateView
Enter FirstFragment#onActivityCreated
Exit FirstFragment#onActivityCreated
Enter FirstFragment#onStart
Exit FirstFragment#onStart
Exit FragmentActivity#onStart
Enter SecondFragment#onStop
Exit SecondFragment#onStop
Enter FirstFragment#onStop
Exit FirstFragment#onStop
Enter FragmentActivity#onResume
Exit FragmentActivity#onResume
Enter SecondFragment#onStart
Exit SecondFragment#onStart
Enter SecondFragment#onResume
Exit SecondFragment#onResume
Enter FirstFragment#onStart
Exit FirstFragment#onStart
Enter FirstFragment#onResume
Exit FirstFragment#onResume
----------------------------------------

3.0のログ
----------------------------------------
Enter FragmentActivity#onCreate
Enter SecondFragment#onAttach
Exit SecondFragment#onAttach
Enter SecondFragment#onCreate
Exit SecondFragment#onCreate
Enter SecondFragment#onCreateView
Exit SecondFragment#onCreateView
Enter FirstFragment#newInstance
Exit FirstFragment#newInstance
Exit FragmentActivity#onCreate
Enter FirstFragment#onAttach
Exit FirstFragment#onAttach
Enter FirstFragment#onCreate
Exit FirstFragment#onCreate
Enter FragmentActivity#onStart
Exit FragmentActivity#onStart
Enter SecondFragment#onActivityCreated
Exit SecondFragment#onActivityCreated
Enter SecondFragment#onStart
Exit SecondFragment#onStart
Enter FirstFragment#onCreateView
Exit FirstFragment#onCreateView
Enter FirstFragment#onActivityCreated
Exit FirstFragment#onActivityCreated
Enter FirstFragment#onStart
Exit FirstFragment#onStart
Enter FragmentActivity#onResume
Exit FragmentActivity#onResume
Enter SecondFragment#onResume
Exit SecondFragment#onResume
Enter FirstFragment#onResume
Exit FirstFragment#onResume
----------------------------------------

全然違う。。。
ぱっと見た感じだと
android-support-v4.jarを利用したほうがバグっているような。。。
3.0のソースを見ることが出来ないから、どんな理由でこのような差分が出ているのか
正確なところは解らない。
でも今のところFragmentを3.0以外で利用するのは控えたほうが無難かも。
少なくともそのまま流用は考えないほうがいいと思う。

2 件のコメント:

  1. はじめまして。
    サンプルとかシーケンスとかめちゃくちゃ参考にさせて頂いております。
    ちょこっとお尋ねしたいんですが、

    >XMLを変えて、Activityを一部増やすことで
    >tablet向けにつくっていたActivityをソースコードをまるまる流用して
    >二つのActivityに分けることが出来ると言っているわけだ。

    これってどのへんに書いています?
    つたない英語力で読んでみたのですが、見つかりません;;

    返信削除
  2. だいぶ昔のコメントですね。。。
    何も反応しなくてしません(^^ゞ

    >XMLを変えて、Activityを一部増やすことで
    >tablet向けにつくっていたActivityをソースコードをまるまる流用して
    >二つのActivityに分けることが出来ると言っているわけだ。
    は、リンク先のブログの中の文章を翻訳したわけではなくて、ブログの内容からブログを書いた人の言いたいことを予想して書いただけです。

    なぜ、私がこのように考えたか?ですが、
    ブログ内をDetailsFragmentで検索すると分かりやすいと思います。
    タブレット側のソースでは、TitlesFragmentのイベントハンドラー内でshowDetails()をコールしてFragmentの内容を変更してますが、
    モバイル向けのサンプルではDetailsActivityのonCreate内で
    DetailsFragment details = new DetailsFragment();
    のようにFragmentのインスタンスを生成しています。
    DetailsFragmentのソースは、まるまる流用しているので、
    >XMLを変えて、Activityを一部増やすことで
    >tablet向けにつくっていたActivityをソースコードをまるまる流用して
    >二つのActivityに分けることが出来ると言っているわけだ。
    のようなブログ記事になったわけです。あえて英語の中で、そんな意味の文章を上げるとしたら以下になると思います。
    With the DetailsFragment already implemented, the implementation of the new activity is very simple because it can reuse the same DetailsFragment from above:

    返信削除