您的位置:首页 > 其它

Activity的生命周期和启动模式

2016-01-13 14:58 309 查看

Activity的生命周期

典型情况下的生命周期分析

onCreate()

第一个生命周期方法,一般在这个方法做初始化工作,比如调用setContentView去加载界面布局资源,初始化Activity所需要的数据等。

onStart()

onRestart()

onResume()

onPause()

可见,但不可交互的情况。一般在这个方法做一些动画暂停操作。同时,onPause()必须先执行完,新的Activity的onResume()才能执行。

onStop()

可做一些稍重量级的回收工作

oDestory()

Activity生命周期里的最后一个回调方法,一般在这里做垃圾回收和资源释放工作。

问题1:

当前Activity为A,用户打开一个新的ActivityB,那么B的onResume()和A的onPause()哪个先执行?

答:Activity的启动过程比较复杂,涉及Instrumentation、ActivityThread和ActivityManagerService(简称:AMS)。简单来说,启动Activity的请求会有Instrumentation来处理,然后它通过Binder小AMS发送请求,AMS内部维护着一个ActivityStack并负责着栈内Activity的状态同步,AMS通过ActivityThread去同步Activity的状态从而完成生命周期的调用。

具体解析:P4-P6

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

资源相关的系统配置发送改变导致Activity被杀死被重新创建。

资源内存不足导致低优先级的Activity被杀死。

如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,所以后台操作适合放入Service中从而保证进程的优先级。

[b]onSaveInstanceState()/onRestoreInstanceState()[/b]

Activity:

在Activity异常终止的时候,系统会调用onSaveInstanceState()来保存Activity的状态,这个方法的调用时机在onStop()之前,可能在onPause()之前,也可能在它之后。当Activity被重新创建的时候,系统或调用onRestoreInstanceState(),并把之前在onSaveInstanceState()所保存的Bundle对象作为参数同时传递给onRestoreInstanceState()和onCreate()方法。onRestoreInstanceState()会在onStart()之后调用。

View:

当Activity在异常情况下需要重新创建的时候,系统会默认为我们保存当前Activity的视图结构,并在重建的时候为我们恢复这些数据,比如文本框中输入的数据,ListView的滚动位置等,这些View相关的状态系统都默认为我们保存恢复,根据View的源码。和Activity一样,每个View都有onSaveInstanceState()/onRestoreInstanceState()。恢复流程:首先Acitivity被意外终止,Activity调用onSaveInstanceState()保存数据,然后Activity会委托Window保存数据,接着Window再委托它上面的顶级容器去保存数据。顶级容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶级容器在一一去通知它的子元素来保存数据。这是一种典型的委托思想,上层委托下层,比如View的绘制,事件的分发等都用到了这种思想。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diy_view);
//可以直接在onCreate中判断并恢复
if(savedInstanceState != null){
String temp_str = savedInstanceState.getString("flag");
}
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("flag","需要保存的参数");
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String temp_str = savedInstanceState.getString("flag");
}


系统配置



横竖屏切换,不重新创建Activity,只需要在AndroidMenifest.xml中的相应的Activity加入:android:configChanges=”orientation|screenSize”即可,代码如下:

<activity
android:name=".activitys.DiyViewActivity"
android:launchMode="singleTop"
android:configChanges="orientation|screenSize"
</activity>


Activity的启动模式

给Activity设置启动模式

第一种:android:launchMode=”singleTask”

第二种:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

不同点:

1.优先级上,两种方式同时存在的时候以第二种为准。

2.第一张无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识的效果,而第二种方法无法为Activity指定singleInstance模式。

standard:标准模式

注意:

在这种模式下,谁启动这个Activity,那么这个Activity就运行这启动它的那个Activity所在的栈中。所以,当用ApplicationContext去启动standard模式的Activity的时候会报错。因为非Activity类型的Context(如Application)并没有所谓的任务栈。

解决方法:用Activity类型的Context去启动,或给待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位。

/*
这时候启动的Activity实际是以singleTask模式启动的。因为类似CSS的最近原则,当launchMode和setFlags同时存在的时候,以setFlags为准。
*/
Intent intent = new Intent();    intent.setClass(DiyViewActivity.this,SpinnerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);


singleTop:栈顶复用模式

如果待启动的Activity已经存在于栈顶则此Activity不会重新创建实例,同时它的onNewIntent()会被回调。通过这个方法的参数我们可以取出当前请求的信息。

@Override
protected void onResume() {
super.onResume();
log("onResume");
if(flag){
Intent intent = new Intent(this,DiyViewActivity.class);
startActivity(intent);
flag=flase;
}
}
/*
输出: onCreate
输出: onStart
输出: onResume
输出: onPause//Activity会先暂停(不可交互),然后调用onNewIntent()
输出: onNewIntent
输出: onResume
*/


Activity第一启动的时候执行onCreate()—>onStart()—>onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()—->onResume(). 如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()—>onStart()—>onResume()等。

注意:

当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

singleTask:栈内复用模式

这是一种单实例模式,如果栈中已经存在,则会调用onNewIntent。具体一点,例如要启动ActivityA,系统首先会寻找是否存在ActivityA想要的任务栈,如果不存在,则创建,然后创建ActivityA后把它发到该任务栈中。

singleInstance:单实例模式。

一种加强的singleTask模式,具有singleTask的所有特性,同时该模式的Activity只能单独位于一个任务栈中。

注意

现在有2个任务栈,前台任务栈为AB,后台任务栈情况为CD,这里假设CD的启动模式均为singTask。现在请求启动D,那么整个后台任务栈都会被切换到前台,这个时候整个后退列表为ABCD,按back键的时候会先弹出D。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: