美文网首页Android开发Android知识
Activity的生命周期(大概是网上最全的版本了)

Activity的生命周期(大概是网上最全的版本了)

作者: billlllllllll | 来源:发表于2017-05-02 09:55 被阅读0次

    生命周期:1.典型情况下的生命周期 :有用户参与的情况下(当然手机的各种状态都是理想情况下)
    2.异常情况下的生命周期:指的是现实情况下,例如手机内容不足。Activity被系统回收,
    还有就是当前Configuration发生变化从而导致Activity被销毁重建等。(Actvity在异常情况下,表现十分微妙。)


    1.典型情况下的生命周期:如下图所示

    如下代码所示:

    public classMainActivityextendsAppCompatActivity {
    private static finalStringTAG="bill";
    @Override
    protected voidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d(TAG,"onCreate()");
    }
    @Override
    protected voidonRestart() {
    super.onRestart();
    Log.d(TAG,"onRestart()");
    }
    @Override
    protected voidonStart() {
    super.onStart();
    Log.d(TAG,"onStart()");
    }
    @Override
    protected voidonResume() {
    super.onResume();
    Log.d(TAG,"onResume()");
    }
    @Override
    protected voidonPause() {
    super.onPause();
    Log.d(TAG,"onPause()");
    }
    @Override
    protected voidonStop() {
    super.onStop();
    Log.d(TAG,"onStop()");
    }
    @Override
    protected voidonDestroy() {
    super.onDestroy();
    Log.d(TAG,"onDestroy()");
    }
    }
    

    上面代码是把activity中所有的生命周期都打印了出来。
    那么我们可以看到,第一次启动的时候运行顺序:

    以下就不意义列举各种正常情况了:
    只写结果:
    1.正常情况下,oncreate() onstart() onresume()
    2.如果当前activity A打开另一个activity B或点击home键进入桌面,那么此时执行activity A的onpause() onstop()方法,当然此时有一种特殊的activity B是不会调用onstop()方法,只是会调用onpause()方法,那就是,此activity B的主题是透明色的。
    3.当回到activity A的时候,调用 onRestart() onstart() onresume()方法
    4.当activity被系统回收以后再次打开,生命周期的调用顺序和1是一样的,但是仅仅是生命周期的调用顺序,并不代表其他过程也一样。
    5.生命周期配对:oncreate() ondestroy()
    onstar() onstop()
    onresume() onpause()

    那么问题来了:
    activity A打开activity B的时候,activity A的onpause()和activity的onResume()方法执行的先后顺序是怎样的?
    打印日志可以看出,两个activity调用的生命周期方法,竟然载同一个线程内,如图

    从上图可以看出,activity A的onpause()方法先执行,然后执行依次activity B的onCreate() onstart() onResume()方法,再去执行A的onstop()等方法。
    另一方面,Android官方也说过,不能在onpause中做一些重量级操作,毕竟要当前的activity先执行完onpause()才能再执行下一个activity的开始生命周期。
    2.异常情况下的生命周期
    1)资源相关的activity发生改变,导致activity被杀死并重建
    例子:资源相关的配置发生改变、系统内存不足的时候,activity可能会被杀死。
    在activity下添加以下方法:

    @Override
    public voidonSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(OUTSTATE,"我被保存下来了");
    Log.d(TAG,"Thread :"+ Thread.currentThread() +",onSaveInstanceState()");
    }
    
    @Override
    public voidonRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if(savedInstanceState !=null) {
    String outstate = savedInstanceState.getString(OUTSTATE);
    Log.d(TAG,"onRestoreInstanceState() outstates = "+ outstate);
    }
    Log.d(TAG,"Thread :"+ Thread.currentThread() +",onRestoreInstanceState()");
    }
    

    分析:资源相关配置发生改变:
    从竖屏转换成横屏的时候,日志如下:

    从横屏转换成竖屏的时候,日志如下:

    此时知道,我们的activity如果屏幕旋转,会造成生命周期的改变,一般来说是这样:
    onpause() -> onsaveinstancestate() -> onstop() -> ondestroy() -> oncreate() -> onstart() -> onrestoreinstancestate() ->onresume()

    而且onrestoreinstancestate()能获取到onsaveinstancestate()保存下来的数据,并且调用顺序是在onstart()方法之后。
    但是,有一点,日志里边没有说明的:onsaveinstancestate()方法的调用时机是在onstop()之前,而且又和onpause()没有时间顺序上的关系。(待验证)
    值得说明的一个是:在执行完activity的onsaveinstancestate()方法之后,还会activity会委托window保存数据,接着window委托他的顶级容器去保存数据,顶层容器是一个viewgroup,然后顶层容器会再去通知他的子元素,例如TextView去调用它的onsaveinstancestate()方法去保存它的数据。这是一个典型的委托思想,在view的绘制过程和分发机制中也是用的类似的思想。

    当系统资源内存不足的时候,会由优先级从低到高依次kill activity。
    这里的优先级划分:前台展示的activity最高,可见但非前台的activity中级,后台activity优先级最低。(这时候可以根据生命周期是否调用onpause onstop方法判断优先级,例如最高级是没有执行两个方法,中级是之执行了onpause方法,最低级是执行了两个方法)
    刚才说的第一种情况,当屏幕的横竖屏改变的时候,activity会重新绘制,会把生命周期先结束再重新开始,那么如果我不想重新绘制activity的话,应该怎么做呢?
    答:在manifest给需要设置的activity添加:android:configChanges="orientation",
    当然在sdk>13的时候还要加上一个属性scrrenSize,变成:android:configChanges="screenSize|orientation",设置了当前的属性,顾名思义:这个是配置改变的时候,屏幕的横竖配置改变的时候。

    并且加上下面的代码:

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        switch(newConfig.orientation){
        case Configuration.ORIENTATION_LANDSCAPE:
        Log.d(TAG,"变成了横着的");
        break;
        case Configuration.ORIENTATION_PORTRAIT:
        Log.d(TAG,"变成了竖着的");
        break;
        }
        }
    

    当屏幕的横竖改变的时候,打印日志为:

    相关文章

      网友评论

        本文标题:Activity的生命周期(大概是网上最全的版本了)

        本文链接:https://www.haomeiwen.com/subject/qhkctxtx.html