Android四大组件(Activity篇)

来源:互联网 发布:社会支持网络 编辑:程序博客网 时间:2024/05/13 15:31

什么是Activity?

Android中,Broadcast负责消息的传递,Service负责后台运行,Content Provider负责数据的共享,而Activity负责界面,它是跟用户交互的接口,是所有控件的容器。

Activity存放在栈中,每当创建一个Activity,便会被扔入栈中,并处于栈顶。当新Activity产生时,旧Activity压栈,新Activity至栈顶。当Activity出站时,便会被销毁,压栈Activity提至栈顶。

Activity的生命周期

Activity有着复杂的生命周期,而其生命周期跟自身的7个接口密不可分。

这里写图片描述

OnCreate:主要完成Activity的初始化操作。例如界面绑定,控件绑定,控件监听。
OnStart:Activity由不可见,变为可见,但此时,尚不能跟用户交互。
OnResume:此时Activity已获取焦点,已可以跟用户进行交互。
OnPause:Activity失去焦点。完成一些不耗时的操作。便于其他Activity提前显示。
OnStop:Activity完全不可见。完成一些耗时的操作。
OnDestroy:Activity将被销毁。
OnRestart:若Activity未被异常回收,则Activity由停止状态,变为运行状态时,触发该接口。

生命周期举例

创建三个Activity A,B和C;A,B,C中各添加一个按钮,用于从A跳转至B,从B跳转至C,从C跳转回A。

(1)打开APP

A: onCreateA: onStartA: onResume

(2)从A启动第二个Activity B

A: onPauseB: onCreateB: onStartB: onResumeA: onStop

在A执行完onPause后,B便开始创建,在B显示完后,才再次调用A的onStop。因此onPause中不要执行过于耗时的任务,以造成界面卡顿。耗时任务应在onStop中进行。

(3)点击HOME键

B: onPauseB: onStop

B并未被销毁。

(4)点击Recent键

B: onRestartB: onStartB: onResume

B再次被激活。

(5)点击Back键

B: onPauseA: onRestartA: onStartA: onResumeB: onStopB: onDestroy

Back键促使B出栈,B被销毁。

(6)锁屏

A: onPauseA: onStop

(7)解锁屏幕

A: onRestartA: onStartA: onResume

(8)关闭APP

A: onPauseA: onStopA: onDestroy

问题来了:
(1)如果在C处于栈顶时,关闭APP(Recent+Del),会如何触发各Activity的生命周期方法?

不同的手机,处理也不同。
Honor

C: onPauseC: onStopA: onDestroy

华为Mate8

C: onPauseC: onStopA: onDestroyB: onDestroyC: onDestroy

(2)OnPause后是否一定触发OnStop?
从生命周期图看,是不一定的。那什么场景中,Activity会只执行到OnPause就停止呢?当新Activity并未全部遮盖旧Activity时。
将Activity B属性加入android:theme=”@style/Base.Theme.AppCompat.Dialog”,则Activity B将以对话框形式出现,不会对Activity A形成遮盖。

A: onPauseB: onCreateB: onStartB: onResume

这里写图片描述

Activity的启动模式

如果A已经存在于栈中,App再次创建一个Activity A,会如何?如果A处于栈顶呢?
对于不同的启动模式,处理操作也不同。

Activity有四种启动模式。

(1)standard:不论A是否在栈内,都创建一个新的实例,入栈置顶。
(2)singleTop:若栈顶Activity为A,则不做任何操作,否则,创建一个新的实例,入栈置顶。
(3)singleTask:如果栈内没有A,则创建一个新的实例,入栈置顶。若存在A,则将A置顶,并将A之上的所有Activity全部出栈。
(4)singleInstance:单独为Activity创建一个栈,公用该栈内的Activity A。

注:此前实例皆为standard模式。

那如何设置启动模式呢?
需要在Manifest中对应的Activity中添加属性android:launchMode=”XXXX”。
默认为“standard”。

这里写图片描述

结合启动模式,再看几个生命周期的例子。
(1)Activity A为SingleTask模式。Activity A启动Activity B。Activity B启动Activity C, 再由Activity C启动Activity A。那么重启Activity A时,生命周期调用如何?

对于Honor和Mate8

B: onDestroyC: onPauseA: onRestartA: onStartA: onResumeC: onStopC: onDestroy

看来,至少华为的处理,并非从栈顶开始,将Activity A之上的Activity出栈的。相反,从紧挨A的Activity入手。

(2)Activity A为SingleInstance模式。Activity A启动Activity B。Activity B启动Activity C。然后依次点击Back键直至App退出。退出时,生命周期调用流程如何?

C: onPauseA: onRestartA: onStartA: onResumeC: onStopC: onDestroyA: onPauseB: onRestartB: onStartB: onResumeA: onStopA: onDestroyB: onPauseB: onStopB: onDestroy

可以看出,C先出栈,之后A再出栈,最后B销毁。
出现这个顺序的原因是,B为SingleInstance,处于单独的栈中(stack 2)。而A,C处于同一栈中(stack 1)。C,A出栈后,stack 1清空,之后对stack 2进行清空。

Activity的几个重要方法

(1)protected void onActivityResult(int requestCode, int resultCode, Intent data)

我们在Activity A中,使用startActivityForResult触发Activity B。当B finish时,将会把Result传回Activity A,Intent即为传回数据。

当然,我们需要在关闭B前,将Intent通过setResult(resultCode, Intent)方法保存。

(2)protected void onSaveInstanceState(Bundle outState)

在系统资源不够用时,android允许杀掉某些Activity。而在这种情况下,系统将会触发Activity的onSaveInstanceState。而开发人员需要做的是,将该Activity需要保存的数据,放到outState这个bundle中。而该bundle即为onCreate的输入参数。
在Create Activity时,可以判断bundle是否为空,进行数据恢复。