Frament 的生命周期小结

分三个部分:

1.fragment 的生命周期。

2.测试。

3.总结。


Frament的生命周期如下:

onAttach(Activity);   

   Called when a fragment is first attached to its activity. 
   关联到Activity时触发

onCreate()
  Called to do initial creation of a fragment 
   在这里可以做一些初始化数据行为。

oncreatView()
 Called to have the fragment instantiate its user interface view. 
 创建要加载显示的View

onViewCreated()
 This gives subclasses a chance to initialize themselves once they know their view hierarchy has been completely created 
  这里获取到 oncreatView()返回的view,一般用于做一些View已经加载完后要做的事情

onActivityCreated();
   Called when the fragment's activity has been created and this fragment's view hierarchy instantiated 
   当关联的Activity被创建后触发。

onViewStateRestore()
 Called when all saved state has been restored into the view hierarchy of the fragment  
  当所有View里面的状态都已经被保存起来时触发。可以用于做一些需要保存状态的View 的初始化工作,比如说Checkbox是否需要被选中等。

onStart();
Called when the Fragment is visible to the user.
当Frament完全呈现给用户时触发。

onResume();
Called when the fragment is visible to the user and actively running
当Frament 保存运行时触发。

onPause();
Called when the Fragment is no longer resumed

onStop();
Called when the Fragment is no longer started

onDestroyView();
Called when the view previously created  oncreatView() has been detached from the fragment

onDestroy();
Called when the fragment is no longer in use.

onDetach();
Called when the fragment is no longer attached to its activity.

测试:


我们在一个activity里面添加一个frament进行测试:

activity 代码:

public class MainActivity extends ActionBarActivity {
    private android.support.v4.app.FragmentManager manager=getSupportFragmentManager();
    private MainActivityFragment fragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("-------activity", "onCreate");
        android.support.v4.app.FragmentTransaction t=manager.beginTransaction();
        fragment=new MainActivityFragment();
        t.replace(R.id.frament_layout,fragment);
        t.commit();
    }

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        Log.i("-------activity","onCreateView    name="+name);
        return super.onCreateView(parent, name, context, attrs);

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("-------activity", "onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("-------activity", "onStop");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("-------activity", "onResume");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("-------activity", "onDestroy");
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Log.i("-------activity", "onDetachedFromWindow");
    }
}

activity 的布局文件:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:layout="@layout/fragment_main" >
    <Button
        android:layout_width="wrap_content"
        android:text="onclick"
        android:layout_height="wrap_content" />
    <FrameLayout
        android:id="@+id/frament_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

    </FrameLayout>
</LinearLayout>

fragment 的代码如下:
public class MainActivityFragment extends Fragment {

    public MainActivityFragment() {
        Log.i("--------frament","MainActivityFragment()");
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.i("--------frament", "onAttach");
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.i("--------frament", "onActivityCreated");
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        Log.i("--------frament", "onViewStateRestored");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("--------frament", "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.i("--------frament", "onDetach");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("--------frament", "onCreate");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.i("--------frament", "onStart");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.i("--------frament", "onStop");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i("--------frament", "onResume");
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.i("--------frament", "onViewCreated");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.i("--------frament","onCreateView");
        return inflater.inflate(R.layout.fragment_main, container, false);
    }
}



运行程序,打印出来的日志如下:
08-22 23:55:57.152    6094-6094/? I/-------activity﹕ onCreateView    name=LinearLayout
08-22 23:55:57.152    6094-6094/? I/-------activity﹕ onCreateView    name=ViewStub
08-22 23:55:57.152    6094-6094/? I/-------activity﹕ onCreateView    name=FrameLayout
08-22 23:55:57.152    6094-6094/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.ActionBarOverlayLayout
08-22 23:55:57.192    6094-6094/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.NativeActionModeAwareLayout
08-22 23:55:57.192    6094-6094/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.ActionBarContainer
08-22 23:55:57.192    6094-6094/? I/-------activity﹕ onCreateView    name=android.support.v7.widget.Toolbar
08-23 00:05:05.060    9921-9921/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.ActionBarContextView
08-23 00:05:05.060    9921-9921/? I/-------activity﹕ onCreateView    name=LinearLayout
08-23 00:05:05.060    9921-9921/? I/-------activity﹕ onCreateView    name=Button
08-23 00:05:05.090    9921-9921/? I/-------activity﹕ onCreateView    name=FrameLayout
08-22 23:55:57.252    6094-6094/? I/-------activity﹕ onCreate

08-22 23:55:57.252    6094-6094/? I/--------frament﹕ MainActivityFragment()
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onAttach
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onCreate
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onCreateView
08-22 23:55:57.252    6094-6094/? I/-------activity﹕ onCreateView    name=RelativeLayout
08-22 23:55:57.252    6094-6094/? I/-------activity﹕ onCreateView    name=TextView

08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onViewCreated
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onActivityCreated
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onViewStateRestored
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onStart
08-22 23:55:57.252    6094-6094/? I/-------activity﹕ onStart
08-22 23:55:57.252    6094-6094/? I/-------activity﹕ onResume
08-22 23:55:57.252    6094-6094/? I/--------frament﹕ onResume

可以看到,先创建activity,activity运行调用oncreate()方法时,开始初始化fragment,执行fragment的生命周期,红色的字可以看到fragment 的加载view也会通过activity oncreateView() 方法,也就是说activity d的oncreateView()方法会监听所有加载到activity window的view,不知道fragment 的view是不是通过activity加载的?加载view 结束后悔调用fragment的 onviewcreated 方法,activity 创建完成,调用onactivityCreated方法,直到下面。有个奇怪的现象,蓝色字体显示,activity 加载xml的view 方法执行是在oncreat()之前,这时还没有调用setcontentviwe() 的方法,这就有点搞不懂, 尽量不要在oncreateview () 做处理,除非有必要。

总结:启动过程先运行activity生命周期,然后跟随着fragment的生命周期。

这里fragmentd 初始化与加载到activity是在oncrate()方法里面执行,假如是在其他生命周期呢,到底会怎么样。

1.放在onstart()下面:
 @Override
    protected void onStart() {
        super.onStart();
        android.support.v4.app.FragmentTransaction t=manager.beginTransaction();
        fragment=new MainActivityFragment();
        t.replace(R.id.frament_layout,fragment);
        t.commit();
        Log.i("-------activity", "onStart");
    }

打印结果如下:
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.ActionBarContextView
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=LinearLayout
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=Button
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=FrameLayout
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreate
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ MainActivityFragment()
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onStart
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onAttach
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onCreate
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onCreateView
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=RelativeLayout
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onCreateView    name=TextView
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onViewCreated
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onActivityCreated
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onViewStateRestored
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onStart
08-23 00:22:34.006  17184-17184/? I/-------activity﹕ onResume
08-23 00:22:34.006  17184-17184/? I/--------frament﹕ onResume

看到fragment 的生命周期跑到了activity 的onstart() 的后面,之前放在oncreate()时是在oncreate();后面,onstart() 前面的。

放在onresume() 下面执行打印结果如下:
08-23 00:28:34.371  19748-19748/? I/-------activity﹕ onCreateView    name=android.support.v7.internal.widget.ActionBarContextView
08-23 00:28:34.371  19748-19748/? I/-------activity﹕ onCreateView    name=LinearLayout
08-23 00:28:34.371  19748-19748/? I/-------activity﹕ onCreateView    name=Button
08-23 00:28:34.391  19748-19748/? I/-------activity﹕ onCreateView    name=FrameLayout
08-23 00:28:34.391  19748-19748/? I/-------activity﹕ onCreate
08-23 00:28:34.411  19748-19748/? I/-------activity﹕ onStart
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ MainActivityFragment()
08-23 00:28:34.411  19748-19748/? I/-------activity﹕ onResume
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ onAttach
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ onCreate
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ onCreateView
08-23 00:28:34.411  19748-19748/? I/-------activity﹕ onCreateView    name=RelativeLayout
08-23 00:28:34.411  19748-19748/? I/-------activity﹕ onCreateView    name=TextView
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ onViewCreated
08-23 00:28:34.411  19748-19748/? I/--------frament﹕ onActivityCreated
08-23 00:28:34.421  19748-19748/? I/--------frament﹕ onViewStateRestored
08-23 00:28:34.421  19748-19748/? I/--------frament﹕ onStart
08-23 00:28:34.421  19748-19748/com.example.administrator.framenttest I/--------frament﹕ onResume

看到了么,fragment 的生命周期跑到了activity 的onresume() 后面了。

所以: fragment的生命周期的执行与activity息息相关,一旦初始化时就会执行它的生命周期。

那么奇怪点,放在onpause()会怎么样,将初始化放在onpause(),运行程序,没有报错就是看不到fragment,这个很正常,因为没有初始化与加载fragment,切换到home,发现打印出来初始化过程,再进入程序,看到fragment了,注意这里fragment调用onstop() 之前没有调用onresume(),打印结果如下,就是这么神奇:
08-23 00:33:26.606  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onPause
08-23 00:33:26.606  21789-21789/com.example.administrator.framenttest I/--------frament﹕ MainActivityFragment()
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onAttach
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onCreate
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onCreateView
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=RelativeLayout
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=TextView
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onViewCreated
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onActivityCreated
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onViewStateRestored
08-23 00:33:26.656  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onStart
08-23 00:33:27.726  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onStop
08-23 00:33:27.726  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onStop
08-23 00:33:51.266  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onStart
08-23 00:33:51.266  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onStart
08-23 00:33:51.266  21789-21789/com.example.administrator.framenttest I/-------activity﹕ onResume
08-23 00:33:51.266  21789-21789/com.example.administrator.framenttest I/--------frament﹕ onResume


注意的时,不能放在onstop()下面,因为在这个方法调用时,activity已经失去焦点,会报错的。



接下还是放在oncreate()下面,切换到home 时,打印如下:
03-28 01:44:46.621      763-763/com.example.administrator.framenttest I/--------frament﹕ onPause
03-28 01:44:46.621      763-763/com.example.administrator.framenttest I/-------activity﹕ onPause
03-28 01:43:22.960  32315-32315/com.example.administrator.framenttest I/--------frament﹕ onStop
03-28 01:43:22.960  32315-32315/com.example.administrator.framenttest I/-------activity﹕ onStop

切换到home后,把这个应用关掉,打印如下:
03-28 01:45:54.467      763-763/com.example.administrator.framenttest I/--------frament﹕ onDestroy
03-28 01:45:54.467      763-763/com.example.administrator.framenttest I/--------frament﹕ onDetach
03-28 01:45:54.467      763-763/com.example.administrator.framenttest I/-------activity﹕ onDestroy
03-28 01:45:54.467      763-763/com.example.administrator.framenttest I/-------activity﹕ onDetachedFromWindow

切换到home 后,一键清理后进入程序这个过程打印如下:
03-28 01:47:34.915    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=LinearLayout
03-28 01:47:34.915    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=Button
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=FrameLayout
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ MainActivityFragment()
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreate
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onCreateView
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=RelativeLayout
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=TextView
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onViewCreated
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onActivityCreated
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onViewStateRestored
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onDestroy
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onDetach
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onAttach
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onCreate
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onCreateView
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=RelativeLayout
03-28 01:47:34.935    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=TextView
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onViewCreated
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onActivityCreated
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onViewStateRestored
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onStart
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onStart
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/-------activity﹕ onResume
03-28 01:47:34.945    2378-2378/com.example.administrator.framenttest I/--------frament﹕ onResume

activity是重新加载一遍,而fragment在初始化后是先调用onstop()之后的生命周期一遍后,再重新加载一遍。



将初始化放在onpause(),下面,所有结果都很正常,切换到home时才初始化,进入时处于onresume() 下面,再切换到home 时初始化,发现又与上面一样,fragment先调用
onresume()下面的生命周期,onDettach() 方法后才重新初始化。那么切换到home后一键清理,再进入应用,acticity果然重新加载,而fragment 像没有受到影响一样直接就onstart() onresume()了。所以我认为,activity 一键清理后内存过低,会重新加载,fragment 会反而难以受到影响,难道是一键清理后activity 的fragment 没有被清理,对oncreate() 做以下处理:
 private String a;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

      if(fragment!=null)
          Log.i("-------activity", "fragment is not null");
        else   Log.i("-------activity", "fragment is null");

        Log.i("-------activity", "onCreate");

        if(a!=null)
            Log.i("-------activity", "a is not null");
        else   Log.i("-------activity", "a is null");


         a="2";
    }

一键清理后进入程序,打印如下:

03-28 02:16:33.492  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=LinearLayout
03-28 02:16:33.492  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=Button
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=FrameLayout
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ fragment is null
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreate
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ a is null
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onCreateView
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=RelativeLayout
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onCreateView    name=TextView
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onViewCreated
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onActivityCreated
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onViewStateRestored
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onStart
03-28 02:16:33.512  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onStart
03-28 02:16:33.522  18884-18884/com.example.administrator.framenttest I/-------activity﹕ onResume
03-28 02:16:33.522  18884-18884/com.example.administrator.framenttest I/--------frament﹕ onResume

可以看到已经为空了,说明被清理了,可是fragment直接就onstart()了,这真是奇怪咯~~我猜是因为activity没有destroy情况下,fragment没有被清理,可以缓存在分类里面,获取fragment也是通过getfragmentManager()。所以清理fragment 时要么主动调用fragment的销毁方法,要么销毁相关联的的activity,如果是重新加载的话,它将完成剩下的生命周期后才会重新开始初始化加载。




总结:

根据测试与体会,总结如下:

1.fragment 的生命周期与关联activity相关,无论放在activity那个生命环节下,只要执行初始化就开始执行生命周期过程。

2.oncreatView()方法是执行加载view 的,不要在里面做处理,无论是activity还是fragment;

3.一键清理后activity 会重新初始化加载,之前的成员变量也全部初始化,而fragment 会保留状态,不会重新初始化,除非主动初始化。如果不是主动控制fragment 的销毁,除     非activity被销毁了,否则再次初始化的时候会先执行完剩下的生命环节才会重新初始化。

4.不要在onstop()里面做有ui的除了,活动已经失去了焦点。

5.不要通过构造器将数据传入fragment




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值