Activity生命周期详解

简介: Activity是由Activity栈进管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。

image.png


一、Activity是由Activity栈进管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。Acitivity一般意义上有四种状态:


1、当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态;


2、当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态;


3、当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态;


4、当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态;


二、在每个不同的状态阶段,Adnroid系统对Activity内相应的方法进行了回调。因此,我们在程序中写Activity时,一般都是继承Activity类并重写相应的回调方法。


1、Activity实例是由系统自动创建,并在不同的状态期间 回调 相应的方法。一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。称之为entire lifetime。


2、当执行onStart回调方法时,Activity开始被用户所见(也就是说,onCreate时用户是看不到此Activity的,那用户看到的是哪个?当然是此Activity之前的那个Activity),一直到onStop之前,此阶段Activity都是被用户可见,称之为visible lifetime。


3、当执行到onResume回调方法时,Activity可以响应用户交互,一直到onPause方法之前,此阶段Activity称之为foreground lifetime。


三、在实际应用场景中,假设A Activity位于栈顶,此时用户操作,从A Activity跳转到B Activity。那么对AB来说,具体会回调哪些生命周期中的方法呢?回调方法的具体回调顺序又是怎么样的呢?


开始时,A被实例化,执行的回调有A:onCreate -> A:onStart -> A:onResume。


当用户点击A中按钮来到B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。


此时如果点击Back键,将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。


至此,Activity栈中只有A。


四、在Android中,有两个按键在影响Activity生命周期这块需要格外区分下,即Back键和Home键。我们先直接看下实验结果:


此时如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。


此时如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。由此可见,Back键和Home键主要区别在于是否会执行onDestroy。


此时如果长按Home键,不同手机可能弹出不同内容,Activity 生命周期 未发生变化(由小米2s测的,不知道其他手机是否会对Activity生命周期有影响)。


横竖屏切换:A.onPause ->A.onSaveInstanceState->A.onStop -> A.onDestroy->A.onCreate -> A.onStart -> A.onRestoreInstanceState ->A.onResume


@Override

public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {

   super.onSaveInstanceState(outState, outPersistentState);

   //Activity 即将销毁时保存数据

}

@Override

public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) {

   super.onRestoreInstanceState(savedInstanceState, persistentState);

   //Activity 重建或者恢复时候取出数据

}


@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
    super.onSaveInstanceState(outState, outPersistentState);
    //Activity 即将销毁时保存数据
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) {
    super.onRestoreInstanceState(savedInstanceState, persistentState);
    //Activity 重建或者恢复时候取出数据
}


五、在AndroidManifest.xml中设置


android:configChanges="orientation|screenSize",切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


注意:


MiniSdkVersion大于等于 13 时候:android:configChanges="orientation" 或者 android:configChanges="orientation|keyboardHidden" 重新调用各个生命周期


MiniSdkVersion小于 13 时候:


1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次


2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次


3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


六、屏幕切换避免,重走Activity生命周期


从上面屏幕切换生命周期可以看出每次切换都在重新创建,为了不必要的麻烦比如视频播放屏幕旋转等,避免重走生命周期就是一个比较好的解决方案


(1)android 2.3之前的版本 android:configChanges="orientation|keyboardHidden"


(2)android 3.0之后的版本 android:configChanges="orientation|screenSize"


七、横竖屏设置


Android横竖屏切换在手机开发中比较常见,很多软件在开发过程中为了避免横竖屏切换时引发不必要的麻烦,通常禁止掉横竖屏的切换。


1、在AndroidManifest. xml 中设置activity中的android:screenOrientation属性值来实现。


(1)竖屏:android:screenOrientation="portrait"


(2)横屏:android:screenOrientation="landscape"


2、在Java代码中通过类似如下代码来设置 (不推荐这种方法,在大的app不同方向启动时会慢)


(1)竖屏: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)


(2)横屏:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)


3、如果要彻底禁止翻转,忽略重力感应带来的切换,(模拟器上不管用,在真机上是正确的)


忽略重力:android:screenOrientation="nosensor"


横竖屏判断:


在onConfigurationChanged里判断,为了onConfigurationChanged在监听屏幕方向变化有效需要以下条件


1、AndroidManifest.xml增加权限:


2、AndroidManifest.xml里设置的MiniSdkVersion和 TargetSdkVersion属性大于等于13


3、在AndroidManifest.xml的Activity里增加:android:configChanges="keyboard|screenSize|orientation|layoutDirection"


4、在onConfigurationChanged(Configuration newConfig)进行判断


//注意:该方法是在AndroidManifest.xml中不设置onConfigurationChanged才能重走生命周期
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if(newConfig.orientation==1){
        //竖屏
    }
    if(newConfig.orientation==2){
        //横屏
    }
}


布局文件设置:


如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下方法来切换布局


1、在res目录下建立layout-land和layout-port目录,相应的layout文件名称不变,比如main.xml。layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,模拟器会自动寻找。


2、在上面横竖屏辨识中,如果横竖屏出现变化,在onCreate()或者onConfigurationChanged()判断方向,就可以在相应的方法中重新setContentView来载入不同的layout xml布局文件


横竖屏切换数据保存与读取


另外,android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!


八、Activity 数据保存与恢复


数据保存:


1、如果因为系统资源紧张而导致Activity的Destory或者旋转屏幕时被destroyed与Recreated, 系统会在用户回到这个Activity时有这个Activity存在过的记录,系统会使用那些保存的记录数据(instance state)它是一些存放在Bundle对象中的key-value pairs,系统默认使用 Bundle保存信息


2、为了可以保存额外更多的数据到instance state,要重写写这个回调函数onSaveInstanceState(Bundle outState),系统会在Activity被异常Destory时传递Bundle对象,这样我们就可以增加额外的信息到Bundle中并保存到系统中。若系统在Activity被Destory之后想重新创建这个Activity实例时,之前的Bundle对象会(系统)被传递到你我们activity的


3、Activity开始stop,系统会调用 onSaveInstanceState(Bundle outState) ,Activity可以用键值对的集合来保存状态信息。这个方法会默认保存Activity视图的状态信息,如在 EditText组件中的文本或 ListView 的滑动位置


数据恢复:


1、当Activity从Destory中重建,我们可以从系统传递的Activity的Bundle中恢复保存的状态。 onCreate() 与 onRestoreInstanceState() 回调方法都接收到了同样的Bundle,里面包含了同样的实例状态信息。


2、由于 onCreate() 方法会在第一次创建新的Activity实例与重新创建之前被Destory的实例时都被调用,我们必须在尝试读取 Bundle 对象前检测它是否为null。如果它为null,系统则是创建一个新的Activity实例,而不是恢复之前被Destory的Activity。


3、也可以选择实现 onRestoreInstanceState() ,而不是在onCreate方法里面恢复数据。 onRestoreInstanceState()方法会在 onStart() 方法之后执行. 系统仅仅会在存在需要恢复的状态信息时才会调用 onRestoreInstanceState() ,因此不需要检查 Bundle 是否为null。


相关文章
|
2月前
|
Java Android开发
Android四大组件之Activity组件
Android四大组件之Activity组件
|
Android开发
深入剖析Android四大组件(一)——Activity生命周期详解(一)
深入剖析Android四大组件(一)——Activity生命周期详解(一)
388 0
深入剖析Android四大组件(一)——Activity生命周期详解(一)
|
存储 Java 数据库
深入剖析Android四大组件(一)——Activity生命周期详解(二)
深入剖析Android四大组件(一)——Activity生命周期详解(二)
124 0
深入剖析Android四大组件(一)——Activity生命周期详解(二)
|
调度 Android开发
深入剖析Android四大组件(八)——结束Activity的4个阶段(二)
深入剖析Android四大组件(八)——结束Activity的4个阶段(二)
180 0
深入剖析Android四大组件(八)——结束Activity的4个阶段(二)
|
Android开发
深入剖析Android四大组件(八)——结束Activity的4个阶段(一)
深入剖析Android四大组件(八)——结束Activity的4个阶段(一)
254 0
|
Android开发
Android四大组件之一Activity生命周期的不同走向
Android四大组件之一Activity的生命周期,欢迎大家阅读
91 0
Android四大组件之一Activity生命周期的不同走向
|
Android开发
Android四大组件之一Activity的生命周期
Activity的生命周期给大家整理好了
79 0
Android四大组件之一Activity的生命周期
|
Java Android开发
Activity的四种启动模式
Android的冷门知识,大家有兴趣可以了解了解
165 0
|
Android开发
Activity四种启动模式
Activity四种启动模式