标签:
Activity生命周期经典图解:
按键对生命周期的影响:
BACK键:
当我们按BACK键时,我们这个应用程序将结束,这时候我们将先后调用onPause()->onStop()->onDestory()三个方法。
再次启动App时,会执行onCreate()->onStart()->onResume()
HOME键:
当我们打开应用程序时,比如浏览器,我正在浏览NBA新闻,看到一半时,我突然想听歌,这时候我们会选择按HOME键,然后去打开音乐应用程序,而当我们按HOME的时候,Activity先后执行了onPause()->onStop()这两个方法,这时候应用程序并没有销毁。
而当我们从桌面再次启动应用程序时,则先后分别执行了onRestart()->onStart()->onResume()三个方法。一般Activity切换正常生命周期(这里的一般是指启动模式为standard,切换activity时没有加flag标志):
ActivityA启动ActivityB:
ActivityA 的生命周期onPause()->onStop(),
ActivityB的生命周期onCreate()->onStart()->onResume()。
ActivityB执行finish返回ActivityA:ActivityB的生命周期onPause()->onStop()->onDestory()
ActivityA的生命周期了onRestart()->onStart()->onResume()
注意:当ActivityB定义为Dialog样式时,ActivityA的生命周期是不一样的,
我们给ActivityB加上theme
<style name="MyDialogStyle"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowFrame">@null</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <item name="android:backgroundDimEnabled">true</item> </style>
还有一点需要特别注意,Activity中直接弹dialog,Acitivity的生命周期是不会变化的。网上有些说法是会执行onPause(),其实并没有执行!
另外还有几个跟生命周期相关的方法
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); }
当应用运行起来后就会开启一条线程,线程中会运行一个任务栈,当Activity实例创建后就会放入任务栈中。Activity启动模式的设置在AndroidManifest.xml文件中,通过配置Activity的属性android:launchMode=""设置。
我们平时直接创建的Activity都是这种模式的Activity,这种模式的Activity的特点是:只要你创建了Activity实例,一旦激活该Activity,则会向任务栈中加入新创建的实例,退出Activity则会在任务栈中销毁该实例。
standard模式是所启动的Activity都是在同一个task容器栈下,不会重新创建新的task容器栈。先压入栈的Activity实例按顺序入栈底,后入栈在栈顶,处于栈的顶部Activity实例处于活动状态,其他处于非活动状态。按物理返回键,退出当前所处活动状态Activity窗口,这样就会从task容器栈中弹出,显示在手机主屏幕上,从而,有非活动状态转换成活动的状态。其次,standard容器栈可能会存在着相同的Activity实例,只有没调用一次startActivity方法,就会创建目标Activity实例对象压入task容器栈。
如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为ABBAD(最先创建的A位于栈底,最后创建的D位于栈顶)
这种模式会考虑当前要激活的Activity实例在任务栈中是否正处于栈顶,如果处于栈顶则无需重新创建新的实例,会重用已存在的实例,否则会在任务栈中创建新的实例。
SingleTop有个不错的用法是防止多次点击创建多个Activity,无论start几次,SingleTop模式能保证栈顶只有一个实例。 如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为ABAD(当B位于栈顶时,再次启动B的时候,B不会重新创建)
如果任务栈中存在该模式的Activity实例,则把栈中该实例以上的Activity实例全部移除,调用该实例的newInstance()方法重用该Activity,使该实例处於栈顶位置,否则就重新创建一个新的Activity实例。
singletask模式,特别需要注意了。启动的目标Activity实例如果已经存在task容器栈中,不管当前实例处于栈的任何位置,是栈顶也好,栈底也好,还是处于栈中间,只要目标Activity实例处于task容器栈中,都可以重用该Activity实例对象,然后,把处于该Activity实例对象上面全部Activity实例清除掉,并且,task容器栈中永远只有唯一实例对象,不会存在两个相同的实例对象。所以,如果你想你的应用不管怎么启动目标Activity,都只有唯一一个实例对象,就使用这种启动模式。 如果Activity启动顺序为A->B->B->A->D,栈中的Acitivy为AD(当A再次被启动时,A会被移到栈顶,位于A上面的Acitivity全部会出栈)
当该模式Activity实例在任务栈中创建后,只要该实例还在任务栈中,即只要激活的是该类型的Activity,都会通过调用实例的newInstance()方法重用该Activity,此时使用的都是同一个Activity实例,它都会处于任务栈的栈顶。此模式一般用于加载较慢的,比较耗性能且不需要每次都重新创建的Activity。
singleInstance启动模式,简单说就是可以共享某个Activity。比如,应用1的任务容器栈中创建了MainActivity实例,应用2也要激活MainActivity,则不需要创建MainActivity实例,直接可以公用MainActivity实例。 尤其值得注意:应用1启动MainActivity,按home键;打开应用2启动应用1的MainActivity实例。在按home键,打开应用1,这时候应用1的界面是应该是处于MainActivity界面实例。 SingleInstance的一个任务栈中只有一个Activity,并保证不再有其他Activity实例进入。
特别需要注意的生命周期onNewIntent
当一个Activity被start,而不需要重新创建时,就会执行onNewIntent生命周期。如果一个Activity的启动模式是SingleTask,我们可以在onNewIntent中执行一些刷新操作等。
我们一般会把MainAcitivy设置为SingleTask,除了保证MainActivity的唯一,还可以利用singleTask的特性做一些清理工作。自动管理栈,销毁无用的Acitivity.
如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考<application>元素的taskAffinity特性)。应用程序默认的affinity的名字是<manifest>元素中设定的package名。
欢迎扫描二维码,关注公众号
标签:
原文地址:http://blog.csdn.net/robertcpp/article/details/51582725