3

大丈夫。ここで私の最初の質問。そして、私はすでにいくつかの解決策を見つけましたが、正直なところ、バックグラウンドで起こっていることは実際にはわかりません. ですから、この問題を少し解決できる人がいるかもしれません。数日間のデバッグの後、私はそれがうまくいったことをうれしく思います...そして、重大なエラーを犯さなかったことを願っています. それでは見てみましょう。

Main-Activity を取得しました。JFeinstein のSlidingFragmentActivityを拡張した単なる FragmentActivityです。さらに、フラグメントの方法に進み、コンテンツ (リストフラグメント、記事フラグメントなど) をフラグメントとしてコンテナー (スライドメニューの右側) に入れることにしました。私のメインコンテナ。ここまでは順調ですね。

重要なフラグメントの 1 つは私の article-fragment です。ViewPager (FragmentStatePagerAdapter を使用) - テキストを含むいくつかのページと、おそらく別のリスト フラグメントを含みます。デバイスを回転させることにするまで、これまでのところ問題はありません。より正確には、記事のフラグメントを更新することにしない限り、デバイスの回転も機能します。

デバイスを回転させるときに、Android がフラグメントの状態を独自に処理することを理解しました (間違っている場合は修正してください)。そして、コンテンツをリロード/更新するまでは、すべて問題ないようです。

では、それをさらに掘り下げてみましょう。最初の起動時に、空のメインコンテナがいくつかありました。次に、記事のフラグメントを初めて読み込んでいます。SupportFragmentAdapter を取得し、ArticleFragment を作成して、メイン コンテナを新しく作成されたタグ付きフラグメントに置き換えるだけです。ロケット科学は不要 - シンプルなトランザクション:

ViewPagerFragment pagerFragment = (ViewPagerFragment) 
    getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT_ARTICLE);

if(pagerFragment != null){
    if(pagerFragment.isResumed()){
        pagerFragment.triggerReload();
    }
} else {
    pagerFragment = new ViewPagerFragment();
    FragmentTransaction t = getSupportFragmentManager().beginTransaction();
    t.replace(R.id.id_main_root_frame, pagerFragment, TAG_FRAGMENT_ARTICLE);
    t.commitAllowingStateLoss();
}

コンテンツをリロードするたびにフラグメントが作成されるのを避けるために、トランザクションの前にフラグメントを取得しようとしています。フラグメントが見つかって再開された場合は、既存のフラグメントでリロードをトリガーします。

この状態でデバイスを回転させます。フラグメントの状態をいじるのを避けるために、フラグメント内に onSaveInstanceState() をそのまま残しました。したがって、フラグメントは破棄されて再作成されただけだと思います。そして、これまでのところすべてが機能しています。しかし、この部分にはブラックボックスのようなものがあると思います。

その後-通常の起動、フラグメントの作成、メインコンテナへの配置、回転デバイス-更新をトリガーします。ただし、タグごとに古い (再作成された) フラグメントを見つける代わりに、何も見つからず、新しいフラグメントが作成されて挿入されます。ここで次の例外が発生したため、少なくとも挿入しようとしました。

java.lang.IllegalStateException: Activity has been destroyed

正確には、 commitAllowingStateLoss() でトランザクションを終了すると、上記の例外が発生します。トランザクションを commit() すると、次の例外が発生します。

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

そこでエラーが発生します。そして、何年にもわたってデバッグと検索を行った後、この質問/回答で、MainActivity の WeakReference で SupportFragmentManager を取得するためのヒントを見つけました。そして、私は何を言うべきですか。私はそれを実装したので、うまくいきます。更新プロセスを少し変更する必要がありましたが、うまくいきました。しかし、いくつかの質問が残ります...

挙動は似ているようです。最初の作成は完璧に機能します。同じようにリロードします - フラグメントはタグで見つかります。回転後、記事は引き続き表示されます。そして、その状態でフラ​​グメントをリロードすると、タグで見つからないため、新しいフラグメントが作成されますが、commit() リクエストは例外をスローしません。デバッガー内を見ると、WeakReference は、このすべてが行われるインスタンス (this) とは別のインスタンス (他の ID) であることがわかります。..

あなたの何人かが私にいくつかのヒントを与えることができれば、素晴らしいでしょう!前もって感謝します!

4

1 に答える 1