• Android Activity生命周期


    一、概念

      1. 每个Activity实例都有其生命周期。在其生命周期内,activity在运行、暂停、停止三种可能的状态间进行转换。每次状态发生转换时,都有一个Activity方法将状态改变的消息通知给activity。

      

           (此图来源于Android书籍权威指南)

      (1). onCreate:表示Activit正在被创建,与其相对应的是onDestory。

       (2). onRestart:表示Activity正在重新启动,一般情况下,Activity从不可见状态到可见状态。

      (3). onStart:表示Activity正在被启动,即将开始,此时,Activity已经可见。与其相对应的是onStop。

      (4). onResume:表示Activity已经可见,并且出现在前台并开始活动。与其相对应的是onPause。

      (5). onPause:表示Activity正在被停止,正常情况下,紧接着onStop被回调。

      (6). onStop:表示Activity即将停止,可以做一些稍微回收工作,但是不能太耗时。

      (7). onDestory:表示Activity即将销毁,这是Activity生命周期最后一个回调,在这里可以做一些回收工作和资源释放。

      PS:Activity整个生命周期中onCreate和onDestory是配对,分别代表时,Activity的创建和销毁,在整个周期中只能调用一次;从Activity是否可见来说,onStart和onStop是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法被多次调用,表示Activity的可见和不可见状态;从Activity是在前台来说,onResume和onPause是配对的,随着用户的操作和设备屏幕的点亮和熄灭,这两个方法被多次调用,表示Activity的在前台和在后台的状态。

    在Activity类中,生命周期的方法:

     1 public class ActivityDemo extends Activity
     2         {
     3             @Override    // 表示Activity正在被创建
     4             public void onCreate(Bundel savedInstanceState){}
     5 
     6             @Override    // Activity从不可见到可见状态
     7             public void onRestart(){}
     8             
     9             @Override   // 表示Activity被启动,已经可见
    10             public void onStart(){}
    11 
    12             @Override    // 表示Activity已经可见了,并且出现到前台开始活动
    13             public void onResume(){}
    14 
    15             @Override    // 表示Activity正在被停止,正常情况下,紧接着onStop()被调用
    16             public void onPuase(){}
    17 
    18             @Override    // 表示Activity即将停止,可以做一些稍微重量级的回收工作,但不能太耗时
    19             public void onStop(){}
    20 
    21             @Override    // 表示Activity即将被销毁,这是Activity生命周期中,最后一个回调,可以做一些回收工作和最终的资源释放
    22             public void onDestroy(){}
    23         }

    PS:在覆盖实现Activity生命周期方法时,在实现中,要先行调用超类(基类)的生命周期方法。Activity生命周期方法,不要自己调用,这个调用由android系统自己进行。Activity直接理解就是一个View从创建到显示,再到消失销毁的整个过程,在这个过程中,Activity状态在不停的转换。

    •  onDestroy()方法在Activity销毁前调用,用于销毁Activity中的对象。
    • onFinish()方法是主动结束Activity的生命周期,在其中会去调用onDestroy()方法。

    2. Activity切换时,生命周期方法执行顺序:

      (1) 在一个Activity进入新建一个Activity时,生命周期方法执行:

    1. 第一个Activity的onPause();
    2. 第二个Activity的onCreate();
    3. 第二个Activity的onStart();
    4. 第二个Activity的onResume();
    5. 第一个Activity的onStop();

      (2) 在新建的Activity返回到前一个Activity时,生命周期方法执行:

    1. 第二个Activity的onPause();
    2. 第一个Activity的onRestart();
    3. 第一个Activity的onStart();
    4. 第一个Activity的onResume();
    5. 第二个Activity的onStop();
    6. 第二个Activity的onDestroy();

      (3) Activity进入后台,再进入前台:

    1. onPause();
    2. onStop();
    3. onRestart();
    4. onStart();
    5. onResume();

      (4) ActivityA、ActivityB、ActivityC,其中ActivityB launchMode=singleTask,并A、B、C依次入栈后,ActivityC通过startActivity(...)启动ActivityB时生命周期:

      1. ActivityC onPause();

      2. ActivityB onRestart();

      3. ActivityB onStart();

      4. ActivityB onResume();

      5. ActivityC onStop();

      6. ActivityC onDestroy();

    3. Activity实例在任务栈重用时,生命周期方法执行顺序:

    1. onPause();
    2. onResume();

    PS: 配置Activity的lauchMode=singleTop。

    二、Activity销毁原因

    • android系统回收内存时,会将暂停或停止的Acitvity销毁。但不会销毁正在运行的Activity。
    • 用户离开当前Activity管理的用户界面,Activity也会被销毁。

    PS:Activity在暂停、停止及销毁前,会先调用onSaveInstanceState(...)方法。

    三、多个Activity切换

      通过startActivity(...)和startActivityForResult(...)进入另一个指定的Activity,Activity在finish()后,调用onDestroy()方法,销毁Activity对象。通过setResult(...)方法,在显示栈中顶层Activity时,标记从哪个Activity返回的。并且,传递返回的数据结构。

      MainActivity.java:

     1 public class MainActivity extends Activity
     2 {
     3     @Override
     4     public void onCreate(Bundle savedInstanceState)
     5     {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_main);
     8 
     9         setupUI();
    10     }
    11 
    12     public void setupUI()
    13     {
    14         LinearLayout navigation = new LinearLayout(this);
    15         navigation.setOrientation(LinearLayout.VERTICAL);
    16         TextView titleView = new TextView(this);
    17         titleView.setText("Main Activity");
    18         LinearLayout.LayoutParams layoutParam = new LinearLayout.LayoutParams(LinearLayout
    19                 .LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    20         layoutParam.gravity = Gravity.CENTER;
    21         navigation.addView(titleView, layoutParam);
    22 
    23         Button pushView = new Button(this);
    24         pushView.setText("进入下一界面");
    25         pushView.setOnClickListener(new View.OnClickListener()
    26         {
    27             @Override
    28             public void onClick(View v)
    29             {
    30                 Toast.makeText(MainActivity.this, "进入下一个界面", Toast.LENGTH_SHORT).show();
    31 
    32                 // intent
    33                 Intent intent = new Intent();
    34                 intent.setClass(MainActivity.this, SecondActivity.class);
    35                 intent.putExtra("title", "第二个界面");
    36                 startActivityForResult(intent, 11);
    37             }
    38         });
    39         navigation.addView(pushView, layoutParam);
    40         addContentView(navigation, layoutParam);
    41     }
    42 
    43     @Override
    44     protected void onActivityResult(int requestCode, int resultCode, Intent data)
    45     {
    46         Toast.makeText(this, "onActivityResult", Toast.LENGTH_SHORT).show();
    47         Intent intent = getIntent();
    48         Toast.makeText(this, "return result finish", Toast.LENGTH_SHORT).show();
    49     }
    50 }

      SecondActivity.java:

     1 public class SecondActivity extends Activity
     2 {
     3     @Override
     4     public void onCreate(Bundle savedInstanceState)
     5     {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_second);
     8 
     9         setupNavigation();
    10     }
    11 
    12     public void setupNavigation()
    13     {
    14         LinearLayout navigation = new LinearLayout(this);
    15         navigation.setOrientation(LinearLayout.HORIZONTAL);
    16 
    17         String title = getIntent().getSerializableExtra("title").toString();
    18         ViewGroup.LayoutParams childParams = new ViewGroup.LayoutParams(LinearLayout
    19                 .LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    20 
    21         Button back = new Button(this);
    22         back.setText("返回");
    23         back.setOnClickListener(new BackLisenter());
    24         navigation.addView(back, childParams);
    25 
    26         TextView titleView = new TextView(this);
    27         titleView.setText(title);
    28         navigation.addView(titleView, childParams);
    29 
    30         LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout
    31                 .LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    32         layoutParams.gravity = Gravity.CENTER;
    33         addContentView(navigation, layoutParams);
    34         Toast.makeText(this, title, Toast.LENGTH_SHORT).show();
    35 
    36     }
    37 
    38     private class BackLisenter implements View.OnClickListener
    39     {
    40         @Override
    41         public void onClick(View v)
    42         {
    43             // 设置返回数据结构
    44             HashMap<String, String> maps = new HashMap<>();
    45             maps.put("id", "001");
    46             maps.put("name", "naray");
    47             Bundle bundle = new Bundle();
    48             bundle.putSerializable("items", maps);
    49             Intent intent = new Intent();
    50             intent.putExtras(bundle);
    51             // 指定返回到栈中顶层的Activity,标记从哪个Activity返回,并传递的数据结构
    52             setResult(9, intent);
    53             // 结构Activity生命周期
    54             finish();
    55         }
    56     }
    57 }

     四、异常情况下Activity的生命周期分析

      4.1 资源相关的系统配置发生改变导致Activity被销毁并重新创建

      比如,当前Activity保处于竖屏状态,如果实然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并且重新创建。当然,这一情况也是可以被阻止的,不让系统重新创建Activity。

      在默认情况下,Activity不做特殊处理,当系统配置发生改变后,Activity就会被销毁,其中的onPause、onStop、onDestory方法会被调用,同时,由于Activity是被异常终止的,系统会调用onSaveInstanceState方法保存当前Activity的场景状态。这个方法在onStop方法调用之前被调用,与onPause方法没有既定的时序关系,即可以在onPause之前,也可以在onPause之后被调用。

      PS:onSaveInstanceState方法只会在Activity异常情况下被终止时被系统调用,在正常情况下Activity的终止是不会被系统调用的。

      在Activity异常终止销毁后,重新创建系统会调用onRestoreInstanceState方法,并且会将Activity被异常终止销毁时,调用onSaveInstanceState方法时,存储的Bundle对象作为参数传递给onRestoreInstanceState和onCreate方法。因此,可以通过onRestoreInstanceState和onCreate方法判断Activity是否是被重新创建的,如果被重新创建了,就取出存储的数据并且恢复之,从时序上来说,onRestoreInstanceState调用时机是在onStart方法调用之后,系统会调用onRestoreInstanceState方法。

      同时,要知道在onSaveInstanceState和onRestoreInstanceState方法,系统默认做了一些事情用于帮忙恢复Activity在创建后,恢复Activity场景状态。 

      Activity异常情况下的销毁和重建(示例为屏幕旋转的情况): 

      

      4.1.1 屏幕旋转时,禁止重建Activity

      通过设置configChanges配置禁止在异常情况下,重建Activity。

    1 <activity
    2         android:name=".Activity.MainActivity"
    3         android:configChanges="orientation|screenSize|keyboardHidden">
    4 </activity>

      然后,重写onConfigurationChanged方法:

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG, "onConfigurationChanged");
    }

      4.2 资源内存不足导致低优先级的Activity被销毁

      这种情况下的数据存储和数据恢复与4.1情况完全一致。在这里我们描述一下Activity的优先级情况。Activity的优先级按照从高到低可以分为三种情况:

      (1). 前台Activity,正在与用户交互的Activity,优先级最高。

      (2). 可见但非前台Activity,比如Activity中弹出一个对话框,导致Activity可见,但是Activity位于后台,无法与用户直接交互。

      (3). 后台Activity,已经被暂停Activity,即执行了onStop方法,优先级最低。

  • 相关阅读:
    Spring学习8- SSH需要的jar包
    Spring学习8-SSH+Log4j黄金整合
    Spring学习8-Spring事务管理(注解式声明事务管理)
    dbvisualizer客户端执行创建存储过程或自定义函数语句的方法
    jvm的组成入门
    java的反射机制
    oracle排序子句的特殊写法与ORA-01785错误
    javascript的数据类型检测
    jsp的el表达式
    javascript模块化编程的cmd规范(sea.js)
  • 原文地址:https://www.cnblogs.com/naray/p/5276241.html
Copyright © 2020-2023  润新知