Activity作为Android的四大组件之一,是一个应用的界面UI,是和用户交互的最直接入口。深入的理解Activity是非常必要的。在MVC模式的Android项目中,Activity同时扮演View和Controller的角色。在MVP模式中Activty只负责View的职能。


1.生命周期


Activity继承自ApplicationContext类,可以重写方法如下:

public class Activity extends ApplicationContext{
 
            protected void onCreate(Bundle savedInstanceState);
 
            protected void onStart();
 
            protected void onRestart();
 
            protected void onResume();
 
            protected void onPause();
 
            protected void onStop();
 
            protected void onDestroy();
 
            protected void onSaveInstanceState(Bundle outState);
 
            protected void onRestoreInstanceState(Bundle savedInstanceState);
 
}


android开发过程中mainactivity是什么 android中mainactivity作用_android




2.四种状态




Running状态:activity调用onResume()方法时,一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
Paused状态:activity调用onPaused()方法时,当Activity被另一个透明或者Dialog样式的Activity覆盖或者按下锁屏键时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
Stopped状态:activity调用onStop()方法时,当Activity不可见时,Activity处于Stopped状态(跳转到其他Activity,或按下Home键回到主屏)。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了。
Killed状态:activity调用onDestroy()方法时,Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。

4种状态中,Running状态和Paused状态是可见的,Stopped状态和Killed状态时不可见的。


3.横竖屏切换时候Activity的生命周期的总结

1、新建一个Activity,并把各个生命周期打印出来

2、运行Activity,得到如下信息


onCreate-->
onStart-->
onResume-->


3、按crtl+f12切换成横屏时


onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->


4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log


onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->


 Android:configChanges="orientation",执行步骤3


onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->


6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged


onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->


7、把步骤5的android:configChanges="orientation" 改成 android:configChanges="orientation|keyboardHidden",执行步骤3,就只打印


onConfigChanged-->
onConfigurationChanged-->


8、执行步骤4


onConfigurationChanged-->
onConfigurationChanged-->


总结:

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

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

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

但是,自从Android 3.2(API 13),在设置Activity的android:configChanges="orientation|keyboardHidden"后,还是一样 会重新调用各个生命周期的。因为screen size也开始跟着设备的横竖切换而改变。所以,在AndroidManifest.xml里设置的MiniSdkVersion和 TargetSdkVersion属性大于等于13的情况下,如果你想阻止程序在运行时重新加载Activity,除了设置"orientation", 你还必须设置"ScreenSize"。

解决方法:

AndroidManifest.xml中设置android:configChanges="orientation|screenSize“

总结一下整个Activity的生命周期:

补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命周期不会有改变

Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState --> onPause --> onStop       onRestart -->onStart--->onResume

Activity未被完全覆盖只是失去焦点:onPause--->onResume



4.四种启动方式



1.standard:


Activity的默认加载方法,即使某个Activity在Task栈中已经存在,另一个activity通过Intent跳转到该activity,同样会新创建一个实例压入栈中。例如:现在栈的情况为:A B C D,在D这个Activity中通过Intent跳转到D,那么现在的栈情况为: A B C D D 。此时如果栈顶的D通过Intent跳转到B,则栈情况为:A B C D D B。此时如果依次按返回键,D  D C B A将会依次弹出栈而显示在界面上。




android开发过程中mainactivity是什么 android中mainactivity作用_android_02



2.singleTop:


如果某个Activity的Launch mode设置成singleTop,那么当该Activity位于栈顶的时候,再通过Intent跳转到本身这个Activity,则将不会创建一个新的实例压入栈中。例如:现在栈的情况为:A B C D。D的Launch mode设置成了singleTop,那么在D中启动Intent跳转到D,那么将不会新创建一个D的实例压入栈中,此时栈的情况依然为:A B C D。但是如果此时B的模式也是singleTop,D跳转到B,那么则会新建一个B的实例压入栈中,因为此时B不是位于栈顶,此时栈的情况就变成了:A B  D B。  


android开发过程中mainactivity是什么 android中mainactivity作用_入栈_03



3.singleTask:


如果某个Activity是singleTask模式,那么Task栈中将会只有一个该Activity的实例。例如:现在栈的情况为:A B C D。B的Launch mo


de为singleTask,此时D通过Intent跳转到B,则栈的情况变成了:A B。而C和D被弹出销毁了,也就是说位于B之上的实例都被销毁了。


android开发过程中mainactivity是什么 android中mainactivity作用_android_04



4.singleInstance:


将Activity压入一个新建的任务栈中。例如:Task栈1的情况为:A B C。C通过Intent跳转到D,而D的Launch mode为singleInstance,则将会新建一个Task栈2。此时Task栈1的情况还是为:A B C。Task栈2的情况为:D。此时屏幕界面显示D的内容,如果这时D又通过Intent跳转到D,则Task栈2中也不会新建一个D的实例,所以两个栈的情况也不会变化。而如果D跳转到C,则栈1的情况变成了:A B C C,因为C的Launch mode为standard,此时如果再按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。


android开发过程中mainactivity是什么 android中mainactivity作用_入栈_05



5.指定启动模式有两种方法: 
1.在AndroidManifest中直接为Activity指定启动模式

<activity        
    android:name=".AnotherActivity"        
    android:launchMode="singleTask"        
    android:taskAffinity="com.andy.task" />


2.在Intent中设置标志位Flags来为Activity指定启动模式
Intent intent = new Intent(this, MyActivity.class);
  intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
  startActivity(intent);
   
   
    
    
   
   
   
   
    
    
    
    
   
   
   
   
    
    3.在优先级上,第二种方式的优先级要高于第一种,如果两者同时存在,则以第二种为准

两者在限定范围上有所差别,第一种方式无法设定“Intent.FLAG_ACTIVITY_CLEAR_TOP”模式,第二种方式无法设定“singleInstance”模式