Activity生命周期

Android中的Activity是可以相互层叠的。我们每启动一个新的Activity,就会覆盖在原来Activity之上。Back键会销毁最上面的Activity
返回栈的概念:在Android系统中,我们是通过任务task来管理ACtivity的,一个任务就是一组存放在栈里面的ACtivity。展示总是最顶层的Activity展示,销毁也是。

Activity的状态

1.运行状态
Activity处于栈顶的位置时候,就是运行状态
2.暂停状态
一个Activity不处于栈顶了仍然可见。
3.停止状态
不处于栈顶,并且完全不可见。系统仍然会为处于停止状态的Activity保留资源
4.销毁状态
Activity从返回移除后就变成了销毁状态,系统倾向于回收处于这种状态的Activity

各种状态被系统回收的优先级:
销毁状态 > 停止状态 > 暂停状态 > 运行状态

Activity的生存期

Activity类中定义了7个回调方法,覆盖了Activity生命周期的每一个环节

android Tthread 销毁 销毁当前activity_xml

我们又可以将上面的7中方法,按照状态来分成两两相对。将Activity分成三种生存期
1.完整生存期:onCreate方法和onDestroy方法之间经理的就是完整生存期。一个onCreate就是一个Activity出生,onDestroy就是一个ACtivity死亡。
2.可见生存期:Activity在onStart方法和onStop方法之间所经历的就是可见生存期,当前Activity不一定能和用户进行交互,但是一定是可见的。我们可以在onStart中加载自选,onstop中释放资源
3.前台生存期:Activity在OnResume()方法和onPause之间经历的就是前台生存期,Activity总是处于运行状态,此时的Activity是可以和用户进行交互的。

图示如下:

android Tthread 销毁 销毁当前activity_xml_02

通过代码体验Activity的生命周期:

首先创建一个新的项目,在layout里面创建两个样式,一个normal_layout.xml一个dialog_layout.xml项目,

两个部分文件里面编写的样式一样,自己定义。文件变一下就行,

android Tthread 销毁 销毁当前activity_android Tthread 销毁_03


最重要的是在AndroidMainfest.xml里面配置主题样式

android Tthread 销毁 销毁当前activity_xml_04


最后我们在MainAActivity里面编写代码:

android Tthread 销毁 销毁当前activity_日志打印_05


android Tthread 销毁 销毁当前activity_日志打印_06

启动程序之后:

可以看到首先打印出日志

android Tthread 销毁 销毁当前activity_启动模式_07


来到当前的主Activity上

android Tthread 销毁 销毁当前activity_日志打印_08


当点击

NormalActivit的按钮,会看到日志打印

android Tthread 销毁 销毁当前activity_android Tthread 销毁_09


Activity页面跳转,说明当前的主Activity不可见了。但是还没有被销毁

android Tthread 销毁 销毁当前activity_日志打印_10

我们点击back之后,回到主Activity

android Tthread 销毁 销毁当前activity_xml_11

日志打印:说明主Activity被重新启动,来到运行状态。

android Tthread 销毁 销毁当前activity_android Tthread 销毁_12

当我们点击第二个按钮的时候:

android Tthread 销毁 销毁当前activity_xml_13

打印日志:由于我们设置Dialog是对话框的主题,所以我们的主Activity仍然对我们是可见的。

android Tthread 销毁 销毁当前activity_xml_14

同样我们点击back之后,回到主页面,日志打印

android Tthread 销毁 销毁当前activity_启动模式_15

最后我们点击back退出app之后日志打印

android Tthread 销毁 销毁当前activity_android Tthread 销毁_16

Activity被回收了怎么保证数据不丢失

场景:当我们的Activity进入了停止状态,由于系统对资源的分配策略。我们的Activity有可能被回收掉。
当我们启动了Activity1,我们再Activity1上面启动了Activity2,Activity1就进入了停止状态,此时如果不慎被系统回收了。那么我们留在Activity1中的数据怎么能保证不丢失。

解决:Activity提供了一个onSaveInstanceState()方法,该方法会在当前Activity回收之前被调用。

android Tthread 销毁 销毁当前activity_日志打印_17

我们在onCreate取数据

android Tthread 销毁 销毁当前activity_android Tthread 销毁_18

重点:发现Bundle和我们Intent类似,Intent也可以结合Bundle一起用于传递数据,我们将数据保存在Bundle中,然后再将Bundle放在Intent里面。
注意:当我们手机屏幕发生旋转的时候,也会进行Activity的创建和销毁。

Activity启动模式

Activity启动模式有四种,分贝是standard,singleTop,singleTask和singleInstance
我们在AndroidMainfest.xml中通过 指定标签android:launchMode来选择启动模式

standard

Activity默认启动模式,在不进行显示指定的情况下,所有Activity都会自动使用这种启动模式。

特点:每启动一个都会位于栈顶,不会考虑栈是是否存在当前的Activity。

代码测试:

android Tthread 销毁 销毁当前activity_xml_19


日志信息:

android Tthread 销毁 销毁当前activity_日志打印_20

singleTop

该模式的特点是,当发现栈顶已经是当前Activity了,就不需要再启动新的Activity,认为可以直接使用它

首先在AndroidMainfest.xml中修改OneActivity的启动模式

android Tthread 销毁 销毁当前activity_android Tthread 销毁_21

MianActivit的代码还有上一个的,多次点击Button,查看日志信息,可以看到只会创建一次实例

android Tthread 销毁 销毁当前activity_android Tthread 销毁_22

如果当前Activity不在栈顶的位置,该模式下还是会创建Activity

修改代码:

android Tthread 销毁 销毁当前activity_日志打印_23


在SecondActivity中

android Tthread 销毁 销毁当前activity_启动模式_24

然后项目运行起来,点击button,查看日志

由于点击之后,OneActivity仍然在栈中,但是并不在顶层,所以会重复创建Activity

android Tthread 销毁 销毁当前activity_日志打印_25

singleTask

每次启动Activity的时候,系统首先会在返回栈中检查是否存在该Activity实例,如果发现已经存在则直接,使用该实例,并把在这个Activity之上所有其他的Activity统统出栈,,如果没有则再创建一个新的Activity实例

编写代码:

首先在OneActivity里面重写Restart(目的是标识OneActivity重启之后,能够体现出来)

android Tthread 销毁 销毁当前activity_xml_26


在SecondACtivity中添加onDestory()

android Tthread 销毁 销毁当前activity_android Tthread 销毁_27


运行之后,打印日志

通过日志打印可以看出:创建的时候,发现栈中已经有了需要的Activity,地址值为一致的。

android Tthread 销毁 销毁当前activity_日志打印_28

singleInstance

指定为singleInstance模式忽的Activity会启用一个新的返回栈来管理这个Activity,相当于解决了Avtivity共享的问题,见名知意,可以类比单例来理解,只不过ACtivity是个需要使用task来承载。所以会新开一个,供全局使用。

代码实现:

首先在AndroidMainfest.xml文件中,将SecondActivity设置为singleInstance

android Tthread 销毁 销毁当前activity_android Tthread 销毁_29


然后改写OneActivity中的代码:

android Tthread 销毁 销毁当前activity_xml_30


修改SeconACtivity中的代码:

android Tthread 销毁 销毁当前activity_日志打印_31


最后编写ThirdActivity中的代码:

android Tthread 销毁 销毁当前activity_日志打印_32


最后运行项目:查看日志

android Tthread 销毁 销毁当前activity_xml_33


图解示意:

android Tthread 销毁 销毁当前activity_android Tthread 销毁_34

Activity实践技巧

1.获取当前Activity

如何根据当前界面判断当前处在哪一个Activity里面呢?

我们使用面向对象的继承特性,在子类中重写方法时会先调用父类的方法,我们先编写一个BaseActivity类,并让其变得可继承(Kotlin中的特性)

android Tthread 销毁 销毁当前activity_android Tthread 销毁_35


我们项目中其他结构的Activity直接继承BaseActivity,由于BaseActivity又是继承AppCompatActivity,本来的功能不受影响

android Tthread 销毁 销毁当前activity_xml_36

这样我们可以查看日志得出结果:

android Tthread 销毁 销毁当前activity_启动模式_37

2.退出程序

问题:键退出程序,我们不需要back,back,bakc退出。直接一键就退出

android Tthread 销毁 销毁当前activity_xml_38

修改BaseActivity中的代码

android Tthread 销毁 销毁当前activity_xml_39

在ThirdActivity中编写退出的逻辑。

android Tthread 销毁 销毁当前activity_日志打印_40

3.启动Activity的最佳写法。
问题:我们再启动一个Activity是,不清楚需要传送那些数据,需要翻看别人写的代码,这样比较麻烦。我们通过一下方式进行改造,提高开发效率

比如在FirstActivity,要启动SecondActivity代码,首先在SecondActivity中编写

android Tthread 销毁 销毁当前activity_xml_41


启动:

android Tthread 销毁 销毁当前activity_android Tthread 销毁_42