Activity生命周期的探索

    xiaoxiao2021-03-25  112

    换一种姿势浏览:http://blog.aiyouweiya.xyz

    Activity:作为四大组件之一,也是与用户交互最多的组件,因此为了更好的交互效果,了解Activity的生命周期,正确分配每个阶段该完成的工作就显得十分必要,例如:我们不能在onPause中做耗时的操作,因为新的Activity必须在前一个Activity执行了onPause才能执行onResume显示。

    Activity的生命周期分为两部分,一部分是典型情况下的生命周期,另一部分是异常情况的生命周期。

    典型情况:正常的生命周期,用户参与的情况。

    异常情况:Activity被收回或者设备的Configuration发生变化导致Activity被销毁并重建。

    1. 典型Activity生命周期分析

    onCreate和onStart:这两个阶段Activity正在创建,可以进行初始化动作,比如setContentView,初始化资源。

    onResume:这时Activity已经前台可见,具备交互功能

    onPause:表示Activity正在停止,这是可以做一些存储数据,停止动画的工作,不能太耗时,不然会影响新的Activity的显示。

    onStop:表示Activity即将停止,这里可以做一些重量级的操作,也不能太耗时

    onDestroy:表示Activity即将销毁,这里可以做一些回收动作和资源释放。

    我的操作及日志情况

    1.完整的生命周期

    2.Activity间跳转的生命周期

    通过上述分析,我们可以清晰的看到生命周期的调用顺序,注意, 1.MainActivity跳到SecondActivity的时候,先是回调MainActivity的onPause,然后才回调SecondActivity的直到onResume的操作,为了SecondActivity尽快切换到前台,不应该在onPause中做太耗时的操作。 2.MainActivity跳到SecondActivity的时候,SecondActivity回调onResume后,调用了MainActivity的onStop,这个方法也不应该有太耗时的操作,不然SecondActivity会有卡顿的情况

    2. 异常情况下的生命周期分析

    2.1 资源相关系统配置改变导致Activity被杀死并重建

    当系统配置变化时,Activity会被销毁,但系统会调用onSaveInstanceState来保存当前的Activity的状态,这个方法在onStop之前调用,然后调用onRestoreInstateState来恢复数据,这个方法在onStart之后调用

    我的操作及日志情况

    MainActivity.java

    /** * 注意到onCreate中也有`Bundle savedInstanceState`,也可以在回调onCreate的时候恢复数据,注意先判断savedInstanceState非空 */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG,"MainActivity-->onCreate"); setContentView(R.layout.activity_main); Log.i("savedInstanceState-->","is null? "+(savedInstanceState==null)+""); editText = (EditText) findViewById(R.id.edit_text); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log.i(TAG,"MainActivity-->onSaveInstanceState"); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); Log.i(TAG,"MainActivity-->onRestoreInstanceState"); }

    通过上述分析,我们可以清晰的看到在切换横竖屏时数据的保存及恢复情况,自己如果有想保存的数据也可以在saveInstanceState中实现,恢复时既可以在onCreate中,也可以在onRestoreInstanceState中,注意, 1.在按下home键,或是切换到另外的Activity时,也会回调onSaveInstanceState保存数据,因为系统也怕在你长时间不操作或内存不足时,Activity被回收,但如果没有发生系统回收,则不会回调onRestoreInstanceState进行数据恢复 2.即便是我们按下home键或者是跳转到另一个Activity在跳转回来之前的Activity仍旧保存着之前的EditText中的状态信息。(Stopped状态下的Activity仍然保存着所有的状态信息和成员变量)

    2.2 内存不足导致低优先级Activity被杀死

    Activity按优先级分三种: (1)前台Activity:正在和用户交互的Activity,优先级高

    (2)可见但非前台Activity:比如有一个AlertDialog弹出时

    (3)后台Activity:执行了onStop的Activity

    内存不足时,系统就会按照优先级由低到高回收Activity

    3. 阻止Activity重建

    由上述栗子我们知道资源相关系统配置改变会导致Activity被杀死并重建,不过我们也可以阻止Activity重建,只需给Activity指定configChanges属性即可。

    例如我们上述的旋转屏幕的栗子,可以给Activity指定orientation和screenSize属性,Activity就不会重建。

    <activity android:name=".MainActivity" android:configChanges="orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.i(TAG,"MainActivity-->onConfigurationChanged newConfigOrientation"+newConfig.orientation); }

    日志信息

    由上述日志可以看出,当我们配置了configChanges后,不会回调onSaveInstanceState和onRestoreInstanceState,也没有onCreate,取而代之的是onConfigurationChanged,因此我们可以在其中实现自己的逻辑,下面一个小demo在onConfigurationChanged根据横竖屏更改EditText中的内容

    @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){ editText.setText("ORIENTATION_LANDSCAPE"); }else if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT){ editText.setText("ORIENTATION_PORTRAIT"); } }

    实现效果如下

    下面为常用的配置引起Activity重建的属性

    项目含义locale切换系统语言keyboardHidden键盘的可访问性发生改变,比如用户调出了键盘orientation屏幕方向发生改变,旋转手机屏幕screenSize屏幕尺寸发生改变,旋转屏幕也会导致屏幕尺寸发生改变,当minSdkVersion和targetSdkVersion均低于13的时候,此选项不会导致Activity重启,否则会导致Activity重启
    转载请注明原文地址: https://ju.6miu.com/read-10219.html

    最新回复(0)