Android四大组件之Activity篇

阅读: 评论:0

Android四大组件之Activity篇

Android四大组件之Activity篇


Android四大组件之Activity篇(二)(Activity的生命周期)

原文链接:点击打开链接


锲而舍之,朽木不折;锲而不舍,金石可镂。——《荀子》

          在上一篇文章中,我们简单的归纳了下Activity的创建、启动、关闭以及数据传送的相关知识点。那么在本篇文章中,我们将重点对Activity的一个比较重要的知识点进行归纳总结,Activity的生命周期,很重要,无论是在平时的开发应用中还是在找工作的笔试面试中,这个问题频频出现,所以很有必要重点归纳总结。这里需要归纳的知识点有Activity的四个状态、七个生命周期方法、三个嵌套循环生命周期、还有特定场景下的生命周期等等……

(1)、Activity的四种基本状态:

              Active/Runing:一个新Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。

              Paused:当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连系,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。

              Stoped:当Activity被另一个Activity覆盖、失去焦点并不可见时处于Stoped状态。

              Killed:Activity被系统杀死回收或者没有被启动时处于Killed状态。

(2)、Activity的几个生命周期方法:

       onCreate创建时调用,或者程序在暂停、停止状态下被杀死之后重新打开时也会调用。

       onStart:onCreate之后或者从停止状态恢复时调用。

       onResume:onStart之后或者从暂停状态恢复时调用,从停止状态恢复时由于调用onStart,也会调用onResume。

       onPause:进入暂停、停止状态,或者销毁时会调用。

       onStop:进入停止状态,或者销毁时会调用。一般我们在这里保存activity的状态信息。

       onDestroy:销毁时调用。在这里一般做些释放资源,清理内存等工作。

       onRestart:从停止状态恢复时调用。

            相对应的生命周期图如下所示:

              

(3)、Activity的三个嵌套生命周期:

                       

            在Activity中用7个方法定义了Activity的完整的生命周期,实现这7个方法,可以帮我们监视其中的三个嵌套生命周期循环:

        ①、Activity的完整的生命周期:自第一次调用onCreate()开始,直至调用onDestory()方法为止。onCreate():可以设置所有“全局”状态以完成初始化。onDestroy():释放所有的系统资源。

        ②、Activity的可视化生命周期:自onStart()调用开始直到相应的onStop()调用结束。这两个方法可以随着应用程序是否为用户可见而被多次调用。

        ③、Activity的前台生命周期:自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。

(4)、Activity中特殊的两个方法:

       Activity的onSaveInstanceState()和onRestoreInstanceState()并不是生命周期方法,他们不同于onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState()会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

       另外,当屏幕的方向放生了改变,Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的onSaveInstanceState()和onRestoreInstanceState()方法,如下:

[java]  view plain copy
  1. public class PreferencesActivity extends Activity {  
  2.     private String name;  
  3.     protected void onRestoreInstanceState(Bundle savedInstanceState) {  
  4.          name = String("name");//被重新创建后恢复缓存的数据  
  5.           RestoreInstanceState(savedInstanceState);  
  6.     }  
  7.     protected void onSaveInstanceState(Bundle outState) {  
  8.          outState.putString("name", "liming");//被摧毁前缓存一些数据  
  9.           SaveInstanceState(outState);  
  10.     }  
  11. }  

        注意: 必须要调用onSaveInstanceState()方法和onRestoreInstanceState()的父类实现,这样默认的父类实现才能保存视图状态的信息。

(5)、横竖屏切换时的Activity的生命周期:

         这里我们需要通过一个实验,然后根据实验结果进行归纳总结,为了整齐,以代码形式给出(来之网络,地址忘了):

[java]  view plain copy
  1. <span style="font-size:14px;color:#000000;">//1、新建一个Activity,并把各个生命周期打印出来  
  2. //2、运行Activity,得到如下信息  
  3.       onCreate-->  
  4.      onStart-->  
  5.      onResume-->  
  6. //3、按crtl+f12切换成横屏时  
  7.       onSaveInstanceState-->  
  8.      onPause-->  
  9.      onStop-->  
  10.      onDestroy-->  
  11.      onCreate-->  
  12.      onStart-->  
  13.      onRestoreInstanceState-->  
  14.      onResume-->  
  15. //4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log  
  16.      onSaveInstanceState-->  
  17.      onPause-->  
  18.      onStop-->  
  19.      onDestroy-->  
  20.      onCreate-->  
  21.      onStart-->  
  22.      onRestoreInstanceState-->  
  23.      onResume-->  
  24.      onSaveInstanceState-->  
  25.      onPause-->  
  26.      onStop-->  
  27.      onDestroy-->  
  28.      onCreate-->  
  29.      onStart-->  
  30.      onRestoreInstanceState-->  
  31.      onResume-->  
  32. //5、修改l,把该Activity添加android:configChanges="orientation",执行步骤3  
  33.      onSaveInstanceState-->  
  34.      onPause-->  
  35.      onStop-->  
  36.      onDestroy-->  
  37.      onCreate-->  
  38.      onStart-->  
  39.      onRestoreInstanceState-->  
  40.      onResume-->  
  41. //6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged  
  42.      onSaveInstanceState-->  
  43.      onPause-->  
  44.      onStop-->  
  45.      onDestroy-->  
  46.      onCreate-->  
  47.      onStart-->  
  48.      onRestoreInstanceState-->  
  49.      onResume-->  
  50.      onConfigurationChanged-->  
  51. //7、把步骤5的android:configChanges="orientation" 改成android:configChanges="orientation|keyboardHidden",执行步骤3,就只打印onConfigChanged  
  52.      onConfigurationChanged-->     
  53. //8、执行步骤4  
  54.      onConfigurationChanged-->  
  55.      onConfigurationChanged--></span>  

对上面的实验结果进行分析,我们可以得出如下结论:

         ①、默认情况下,当“屏幕方向”或“键盘显示隐藏”变化时都会销毁当前的Activity,创建新的Activity。

         ②、默认情况下(没有设置android:configChanges属性):

                >>> 竖屏切换横屏:销毁当前Activity之后,创建一个新的Activity实例。

                >>> 横屏切换竖屏:销毁当前的Activity之后,创建一个新的Activity实例,新的Activity实例很快就被销毁,接着又会创建一个新的Activity实例。如果只希望创建一个实例,可以配置android:configChanges="orientation";

那么基于上面的知识点,在日常的开发中,如果我们不想在横竖屏切换时让Activity销毁该怎么办呢?

 方法一:①、在l中为Activity设置configChanges属性,如下:

[java]  view plain copy
  1. <application android:icon = “@drawable/icon”   android:label = “@string/app_name”>  
  2.       <activity android:name = “.MainActivity”  android:label = “@string/app_name”  
  3.                      android:configChanges = “orientation|keyboardHidden”>  
  4.           <intent-filter>  
  5.             ……  
  6.             </intent-filter>  
  7.       </activity>  
  8. </application>  

       上面的android:configChanges属性指定了要捕获“屏幕方向”和“键盘显示隐藏”变化,当捕获到这些变化后会调用Activity的onConfigurationChanges()方法。
       configChangesconfig有如下选项:

                 orientation: 屏幕在纵向和横向间旋转;
                 keyboardHidden: 键盘显示或隐藏;
                 fontScale:用户变更了首选的字体小;
                 locale :用户选择了不同的语言设定;
                 keyboard:键盘类型变更,例如手机从键盘切换到全键盘;
                 touchscreen或navigation:键盘或导航方式变化;

       注意:如果缺少了keyboardHidden选项,不能防止Activity的销毁,并且在之后提到的onConfigurtionChanged事件中只能捕获竖屏变横屏的事件,不能捕获横屏变竖屏的事件。

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

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

                 ②、在对应的Activity中重写:onConfigurationChanged方法:

[java]  view plain copy
  1. public class MainActivity extends Activity {       
  2.        private TextView textView;       
  3.        @Override       
  4.        public void onCreate(Bundle savedInstanceState) {           
  5.              Create(savedInstanceState);           
  6.              setContentView(R.layout.main);           
  7.              Log.i("--Main--", "onCreate");           
  8.              textView=(TextView)findViewById(R.id.tv_id);       
  9.        }  
  10.        @Override       
  11.        public void onConfigurationChanged(Configuration newConfig) {           
  12.              ConfigurationChanged(newConfig);           
  13.              Log.i("--Main--", "onConfigurationChanged");  
  14.              ientation==Configuration.ORIENTATION_LANDSCAPE){               
  15.                   textView.setText("当前屏幕为横屏");           
  16.              }else{    
  17.                   textView.setText("当前屏幕为竖屏");           
  18.              }       
  19.        }        
  20. }  

   注:如果项目不需要屏幕切换时可以设置为:

       1、 android:screenOrientation="portrait"始终以竖屏显示 

              2、 android:screenOrientation="landscape"始终以横屏显示

方法二:上面是通过配置文件设置屏幕的横竖屏切换的,下面通过代码区控制屏幕的横竖屏切换:

[java]  view plain copy
  1.   private OnClickListener onClick=new OnClickListener() {           
  2.          @Override           
  3.          public void onClick(View v) {               
  4.                //设置屏幕为横屏              
  5.                   if(v==butLandscrpe){   
  6.                       MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);               
  7.                   }else{   
  8.                       //设置为置屏幕为竖屏  
  9.                           MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  
  10.                }  
  11.          }  
  12. };  
  13. //监听系统设置的更改     
  14.  @Override   
  15. public void onConfigurationChanged(Configuration newConfig) {           
  16.         ConfigurationChanged(newConfig);           
  17.         String message&#ientation==Configuration.ORIENTATION_LANDSCAPE?"屏幕设置为:横屏" : "屏幕设置为:竖屏";         
  18.         showToast(message);      
  19. }  

(6)、Back键和Home键相关的Activity的生命周期:

                      当我们按Back键时,我们当前的Activity界面退出,我们看不到了,这时候我们先后调用了onPause() -> onStop() -> onDestory()三个方法;

              当我们正在浏览一个新闻页面的时候,突然想听歌了,那么我们会选择按Home键,然后去打开音乐应用程序,而当我们按Home的时候,对应的新闻页的Activity先后执行了onSaveInstanceState() -> onPause() -> onStop()这几个方法,这时候应用程序没有销毁。而当我们再次启动Activity的应用程序时,则先后分别执行了onRestart() -> onStart() -> onResume() 这几个方法。

                 注意:这里要知道几种情形的Activity相对应的生命周期方法的调用过程,分别为:打开一个应用、关闭一个应用、完全覆盖(停止)、没有完全覆盖(暂停)、屏幕的横竖屏切换、Back和Home键等。

  网上看到的一个关于Activity的生命周期管理的系列文章挺好,地址
                            .html


本文发布于:2024-02-01 04:46:38,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170673400033964.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:组件   Android   Activity
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23