活动和片段生命周期和取向的变迁 [英] Activity and Fragment Lifecycles and Orientation Changes

查看:131
本文介绍了活动和片段生命周期和取向的变迁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直有与片段和已强制力关闭,并没有遵循一个逻辑模式的方向变化。

I have been having very odd issues with Fragments and orientation changes that have been causing force closes and not following a logical pattern.

我创建了一个简单的活动片段生命周期中调试应用程序,它只是实现的Activity生命周期和的片段生命周期通过报告调用logcat中。

I created a simple Activity and Fragment lifecycle debugging application which simply implements every step of the Activity lifecycle and Fragment lifecycle by reporting the call to the logcat.

下面是 TestActivity TestFragment 类:

TestActivity

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();
    }
}

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();
    }
}

在初始化时,logcat的输出跟随预期的顺序(启动活动,当片段连接,其生命周期的呼叫发生,等等):

On initialising, the Logcat output follows the expected order (start Activity, when the Fragment is attached, its lifecycle calls happen, etc):

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的文档说:即:

当这种变化发生时,机器人重新启动运行活动(的onDestroy()被调用,随后的onCreate())

When such a change occurs, Android restarts the running Activity (onDestroy() is called, followed by onCreate())

这将表明它应该关闭活动及其内容,如生命周期建议(和它),但是经过同样的订购过程中重新创建活动在新的方向。这发生,似乎片段正在尝试重新创建和然后一个新的创建在活动的娱乐。

Which would suggest that it should shut down the Activity and its contents like the lifecycle suggests (and it does) BUT then go through the same ordered process recreating the Activity in the new orientation. This doesn't happen and it seems that the Fragment is attempted to be recreated and then a new one is created in the activity recreation.

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

显然有很多的解决方案来解决这个问题,但我的问题是为什么会出现这种情况?为什么一个片段引用保持并重新创建时,它应该是该活动按理说它是一部分的完全破坏并重新创建?我可以证明,通过片段取值故意是分开来的活动。但是,是什么原因导致的问题,是为什么与原片段连接并重新创建的之前活动是?它只是似乎并不遵循逻辑生命周期的安卓过程的其余部分一样。

Obviously there are plenty of solutions to solve this, but my question is why does this happen? Why is a Fragment reference maintained and recreated when it is supposed to be part of that Activity which is supposedly completely destroyed and recreated? I can justify that by Fragments intentionally being separate to activities. But what was causing the issues, is why is the original Fragment attached and recreated before the Activity is? It just doesn't seem to follow the logical lifecycle that the rest of the Android process does.

推荐答案

这是因为活动要求的onSaveInstanceState(捆绑)之前被销毁。默认情况下,该活动是节省其片段的状态在此方法。

This happens because the activity calls onSaveInstanceState(Bundle) before being destroyed. By default, the activity is saving the states of its fragments in this method.

之后,重新创建活动的时候,老段在活动中重新创建的onCreate(包savedInstanceState)方法。

Later, when the activity is re-created, the old fragments are re-created in the activity onCreate(Bundle savedInstanceState) method.

您可能要检查源$ C ​​$ C <一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/app/FragmentActivity.java#FragmentActivity.onSaveInstanceState%28android.os.Bundle%29">here和<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.0.1_r1/android/support/v4/app/FragmentActivity.java#FragmentActivity.onCreate%28android.os.Bundle%29">here更好地理解这种行为。

You might want to check the source code here and here to better understand this behaviour.

这篇关于活动和片段生命周期和取向的变迁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆