XJL's Blog

保持乐观、单纯。 要开心。

爱家人朋友,爱猫咪,爱学习。


Activity 生命周期

Activity 是Android 四大组件之一,也是日常开发过程中最最常用的组件了。

avatar

Activity生命周期的7个方法说明:

onCreate(), onStart(), onResume(), onPause(), onStop(), onRestart(), onDestory()

方法名称 描述 用途举例 下一方法
onCreate() 当Activity第一次创建时调用。该方法(如果有)会提供给你一个包含之前
活动的冻结状态信息bundle.
进行一系列初始化的操作时。例如:创建View,加载视频数据等等。 onStart()
onRestart() 当Activity 状态为onStop()重新唤起后调用的方法 当活动停止后重新启动该活动时调用(不常用),针对停止后重启操作。 onStart()
onStart() 该方法代表Activity正在被启动,此时Activity已经可见,但是此时Activity还未到前台,因此用户还无法看到,无法响应用户的交互互动作。 - onResume()
onResume() 当Activity将开始与用户进行交互时调用。在这个时间点你的活动将会在活动堆栈的顶端,用户输入将会访问它。 暂停后恢复我们会在该方法中进行一些操作,例如视频继续播放 onPause()
onPause() onPause方法表示Activity正在暂停,正常情况下,onStop紧接着就会被调用。 该方法十分重要,用来做信息持久化存储操作以及停止消耗CPU资源操作,如记录视频播放进度时间,以及暂停视频播放操作等。 onStop()或onResume()
onStop() 表示Activity即将停止,可以做一些稍微重量级的资源回收工作等,同样也不能太耗时。 界面将会隐藏或销毁,做一些重要信息或未被存储的信息的存储操作。但也不要太耗时。如存储用户信息等操作,以及用户此次观看的视频地址以及时间,便于下次打开该界面时继续播放。 onDestory或onRestart()
onDestory() Activity被销毁钱最后一个被调用的方法。这个方法将会发生因为活动将会结束(在活动中调用finish()方法,或者系统临时销毁该实例节约空间。你可以使用isFinishing()方法区别这两种场景)。 界面将要销毁,释放一些实例节约空间,如置空List集合等。 -

Activity 阶段状态:
Activity 四种主要状态

一个Activity 从本质上讲拥有4种状态:

  • 运行:如果当前Activity 在前台界面(堆栈栈顶)
  • 暂停:当ActivityA 被另一个非全屏ActivityB(如一个对话框) 覆盖时,ActivityA将会暂停,一个暂停的Activity也是可以货源的(他的成员和成员信息将会保留),当在内存资源缺乏时将会被系统回收。
  • 停止: 当ActivityA 被另一个全屏ActivityB 覆盖时,那么ActivityA将处于停止状态,该活动也仍保留全部的状态和成员信息,但将会被隐藏起来不再展示给用户,并且当内存在其他地方被需要时该活动就将会被系统杀死。
  • killed:这个activity已经被销毁,其所有的状态信息和成员变量已经不存在了。

状态转换:

Activity 状态转换

# Activity 启动模式:

名称 描述
standard 标准模式
singleTop 栈顶复用
singleTask 任务栈单例
singleInstance 单任务栈模式

四种模式详解:

standard:

标准模式,每次启动一个Activity 都会创建一个实例。

singleTop:

栈顶复用模式,即start的Activity 已经在栈顶的话,就会直接复用实例,此时在Intent 中传递的数据会在onNewIntent 方法中回调。如果目标Activity 不在栈顶,那么将创建一个新的实例。举例:一般的推送消息详情:收到推送通知时,用户点击消息后打开的Activity 会设置为singleTop 模式,方便复用。

singleTask:

任务栈单例模式,一个任务栈中只会存在一个这样的实例。当start 目标实例时候,不存在该实例则创建一个新的实例,如果存在,则会移除该实例上面的所有实例,将该实例处于栈顶,且回调onNewIntent 方法。举例:少数情况下销毁Activity :设置MainActivity 为singleTask 模式,当重新启动时候,他会销毁在他之前的所有Activity实例。

singleInstance:

单任务栈模式,该Activity 独享一个Activity 栈,且只有一个实例。如果已经启动该实例,再次启动将会调用onNewIntent 方法。

两个Activity之间跳转必然会执行的是哪几个方法:

  • 一般情况比如说有两个activity,分别叫A、B ,当在A里面激活B组件的时候,A 会调用 onPause()方法,然后B 调用onCreate、onStart、 OnResume,这个时候B覆盖了窗体,A会调用onStop方法. 。

  • 如果B是个透明的界面,或者是对话框的样式,,就不会调用onStop方法。

横竖屏切换的生命周期变化

这个生命周期跟清单文件里的配置有关系:

  • 不设置Activity的android:configChanges时,切屏会销毁当前Activity,然后重新加载,重新调用各个生命周期。onPause —> onStop —> onDestory —> onCreate —>onStart —> onResume。

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

Android 进程优先级

** 前台进程:Foreground process **

  • 用户正在交互的Activity
  • 当某个Service 绑定正在交互的Activity
  • 被主动调用为前台的service(startForeground())
  • 组件正在执行生命周期的回调(onCreate(), onStart(), onDestory())
  • BroadcastReceier 正在执行onReceive()

可见进程:Visible process

  • Activity 处于onPause()(没有进入onStop())
  • 绑定到前台Activity 的service

服务进程:Service process

  • 简单的startService()启动

后台进程:Background process

  • 对用户没有直接影响的进程 — Activity 处于onStop() 的时候,android:process = ”:xxx“

空进程:Empty process

  • 不含有任何的活动的组件。(Android设计的,处于缓存的目的,为了第二次启动更快,采取的一个权衡)

App 的入口

Android 是基于Java 语言的,而Java 有main()方法,那么Android 的主入口在哪里?

答案:有main()方法,main()方法在ActivityThread 类中的第6041行main(String[] args)

Scheme 跳转协议

Scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的Scheme 协议,可以方便的跳转到app 的各个页面;

通过Scheme 协议,服务于可以定制化地告诉app应该换到哪个页面,可以从通知栏或H5 页面跳转到其他页面。

扩展补充:

后台的Activity 由于某种原因被系统回收了,如何在被系统回收前保存当前状态?

除了在栈顶的Activity ,其他的Activity 都有可能在内存不足时被系统回收掉,一个Activity 越处于栈底,被回收的可能性就越大;

一般情况下,调用onPause() 和onStop() 方法之后的Activity 实例仍然存在内存中,Activity 的所有信息和状态数据都不会消失,当Activity 重新回到前台之后,所有的改变都会得到保留。但当系统内存不足时,调用onPause() 和onStop() 方法后的Activity 可能会被系统销毁,此时内存中就不存在该Activity 的实例了,如果这个时候Activity 重新回到前台,之前所作的改变就会消失;

为了避免以上情况,我们可以覆写onSaveInstanceState() 方法。onSaveInstanceState() 方法接收一个Bundle 类型的参数,将需要保存的数据存储在这个Bundle 对象中,这样即使Activity 被系统销毁,当用户重新启动这个Activity 而调用它的onCreate() 方法时,上述的Bundle 对象会被作为实参传递给onCreate() 方法,这时可以从Bundle 中取出保存的数据,然后利用这些数据将Activity 恢复到被销毁之前的状态;

但是有些情况下,上述方式并不能完美解决该问题,例如正在播放视频时,手机突然没电或其他意外情况导致关机,这时想要在重新开机打开app后恢复之前的状态,我们可以每隔一段时间将所需数据保存在手机本地(数据库或者文件),等下次重新打开时,读取本地文件恢复之前播放的进度即可。

最近的文章

Activity 事件分发机制-基础

长期以来对Android 事件分发机制的理解都是停留在模棱两可,甚至可以说是蜻蜓点水的程度,最近系统的学习了一下,理解的较为全面,将自己的理解记录在该博客下,可能会分为几篇博客吧!本文是在理解了https://www.cnblogs.com/chengxuyinli/p/9979826.html 的基础上整理,感谢大佬的博客,浅显易懂,解决了我长期以来的疑惑。时间分发的对象 事件 触发场景 单次事件流中触发的次数 ...…

继续阅读
更早的文章

Welcome To MyBlog

欢迎访问我的博客。本博客主要用来记录个人的一些技术分享、学习心得、代码分享等。…

继续阅读