13

私は非常に奇妙な問題を抱えておりFragments、方向の変更により強制終了が発生し、論理的なパターンに従っていません。

logcat への呼び出しを報告することで、 Activity ライフサイクルFragment ライフサイクルのすべてのステップを単純に実装する、単純なライフサイクル デバッグ アプリケーションを作成しましActivityFragment

TestActivityおよびTestFragmentクラスは次のとおりです。

テスト活動

public class TestActivity extends Activity {
    Context ct = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.e("ACT", "onCreate called");

        ct = getApplicationContext();

        FrameLayout fl = new FrameLayout(ct);
        fl.setId(1000);

        TestFragment tf = new TestFragment();
        getFragmentManager().beginTransaction().add(fl.getId(), tf, "").commit();

        setContentView(fl);
    }

    @Override
    protected void onStart() {
        Log.e("ACT", "onStart called");
        super.onStart();
    }

    @Override
    protected void onResume() {
        Log.e("ACT", "onResume called");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.e("ACT", "onPause called");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.e("ACT", "onStop called");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.e("ACT", "onDestroy called");
        super.onDestroy();
    }

    @Override
    protected void onRestart() {
        Log.e("ACT", "onRestart called");
        super.onRestart();
    }
}

テストフラグメント

public class TestFragment extends Fragment {
    Context ctFrag = null;

    @Override
    public void onAttach(Activity activity) {
        Log.e("FRAG", "onAttach called");
        super.onAttach(activity);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.e("FRAG", "onCreate called");

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Log.e("FRAG", "onCreateView called");

        ctFrag = ((TestActivity) getActivity()).ct;

        TextView tv = new TextView(ctFrag);
        tv.setText("My test TextView");

        return tv;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.e("FRAG", "onActivityCreated called");
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        Log.e("FRAG", "onStart called");
        super.onStart();
    }

    @Override
    public void onResume() {
        Log.e("FRAG", "onResume called");
        super.onResume();
    }

    @Override
    public void onPause() {
        Log.e("FRAG", "onPause called");
        super.onPause();
    }

    @Override
    public void onStop() {
        Log.e("FRAG", "onStop called");
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        Log.e("FRAG", "onDestroyView called");
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        Log.e("FRAG", "onDestroy called");
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        Log.e("FRAG", "onDetach called");
        super.onDetach();
    }
}

初期化時に、Logcat の出力は予想される順序に従います ( start ActivityFragmentが接続されている場合、そのライフサイクル呼び出しが発生するなど)。

01-29 10:12:50.270: E/ACT(3321): onCreate called
01-29 10:12:50.760: E/FRAG(3321): onAttach called
01-29 10:12:50.760: E/FRAG(3321): onCreate called
01-29 10:12:50.760: E/FRAG(3321): onCreateView called
01-29 10:12:50.770: E/FRAG(3321): onActivityCreated called
01-29 10:12:50.770: E/ACT(3321): onStart called
01-29 10:12:50.770: E/FRAG(3321): onStart called
01-29 10:12:50.770: E/ACT(3321): onResume called
01-29 10:12:50.770: E/FRAG(3321): onResume called

しかし、問題は、向きの変更が発生したときに、Android のドキュメントに次のように記載されていることです。

このような変更が発生すると、Android は実行中のアクティビティを再起動します (onDestroy() が呼び出され、次に onCreate() が呼び出されます)。

これは、ライフサイクルが示唆するように とその内容をシャットダウンする必要があることを示唆していActivityます (そして実際にそうしています) Activity。これは起こらず、をFragment作成しようとして、アクティビティ レクリエーションで新しいものが作成されたようです。

01-29 10:17:52.249: E/FRAG(3321): onPause called
01-29 10:17:52.259: E/ACT(3321): onPause called
01-29 10:17:52.269: E/FRAG(3321): onStop called
01-29 10:17:52.269: E/ACT(3321): onStop called
01-29 10:17:52.279: E/FRAG(3321): onDestroyView called
01-29 10:17:52.299: E/FRAG(3321): onDestroy called
01-29 10:17:52.299: E/FRAG(3321): onDetach called
01-29 10:17:52.299: E/ACT(3321): onDestroy called
01-29 10:17:52.650: E/FRAG(3321): onAttach called
01-29 10:17:52.650: E/FRAG(3321): onCreate called
01-29 10:17:52.650: E/ACT(3321): onCreate called
01-29 10:17:53.020: E/FRAG(3321): onCreateView called
01-29 10:17:53.020: E/FRAG(3321): onActivityCreated called
01-29 10:17:53.030: E/FRAG(3321): onAttach called
01-29 10:17:53.030: E/FRAG(3321): onCreate called
01-29 10:17:53.030: E/FRAG(3321): onCreateView called
01-29 10:17:53.030: E/FRAG(3321): onActivityCreated called
01-29 10:17:53.060: E/ACT(3321): onStart called
01-29 10:17:53.060: E/FRAG(3321): onStart called
01-29 10:17:53.060: E/FRAG(3321): onStart called
01-29 10:17:53.060: E/ACT(3321): onResume called
01-29 10:17:53.060: E/FRAG(3321): onResume called
01-29 10:17:53.060: E/FRAG(3321): onResume called

明らかに、これを解決するための解決策はたくさんありますが、私の質問は、なぜこれが起こるのですか? 完全に破棄されて再作成されると思われるものの一部であるはずの参照が、なぜFragment維持され、再作成されるのでしょうか? 意図的にアクティビティから切り離すことで、それを正当化できます。しかし、何が問題を引き起こしていたのですか?なぜオリジナルが取り付けられ、そのに再作成されたのでしょうか? Android プロセスの残りの部分が行う論理的なライフサイクルに従っていないようです。ActivityFragmentFragmentActivity

4

2 に答える 2

10

これは、アクティビティonSaveInstanceState(Bundle)が破棄される前に呼び出すために発生します。デフォルトでは、アクティビティはフラグメントの状態をこのメソッドに保存しています。

その後、アクティビティが再作成されると、古いフラグメントがアクティビティonCreate(Bundle savedInstanceState)メソッドで再作成されます。

この動作をよりよく理解するために、ここここでソース コードを確認することをお勧めします。

于 2013-01-30T10:04:41.823 に答える
1

これは、アクティビティが再作成されるときにフラグメントを何度も追加しているためです。アクティビティの onCreate メソッドで以下のコードを使用して、フラグメントの再作成を回避できます。

if(savedInstanceState == null) 
{
    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}

構成の変更が発生しても、古いフラグメントは破棄されません。再作成されると、アクティビティに再び追加されます。

于 2015-12-01T09:26:32.723 に答える