活动和片段生命周期和方向变化

B T*_*B T 13 android android-lifecycle android-fragments android-activity

我一直有非常奇怪的问题Fragments和方向更改导致强制关闭而不遵循逻辑模式.

我创建了一个简单ActivityFragment生命周期调试应用程序,它只是实现的每一步活动的生命周期片段的生命周期由报告调用logcat的.

以下是TestActivityTestFragment类:

测试活动

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

TestFragment

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

初始化时,Logcat输出遵循预期的顺序(开始Activity,Fragment附加时,其生命周期调用发生等):

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
Run Code Online (Sandbox Code Playgroud)

但问题是,当方向发生变化时,Android文档会说:

当发生这样的更改时,Android会重新启动正在运行的Activity(调用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
Run Code Online (Sandbox Code Playgroud)

显然有很多解决方案可以解决这个问题,但我的问题是为什么会发生这种情况?为什么Fragment在它被认为Activity完全被破坏和重新创建的那部分被维护和重新创建的时候?我可以通过Fragment故意将其与活动分开来证明这一点.但是,是什么原因导致的问题,就是为什么是原来的Fragment连接和重建Activity是什么?它似乎并不遵循Android进程其余部分所遵循的逻辑生命周期.

Kéz*_*éza 10

发生这种情况是因为活动onSaveInstanceState(Bundle)在被销毁之前调用.默认情况下,活动正在此方法中保存其片段的状态.

稍后,当重新创建活动时,将在活动方法中重新创建旧片段onCreate(Bundle savedInstanceState).

您可能要检查的源代码在这里,并在这里更好地理解这种行为.

  • 那是对的,谢谢你.我的问题似乎取决于`onCreate`调用中我称之为`super.onCreate()`的位置.既然我知道为什么会发生这种情况,我可以解决它,谢谢你. (3认同)