安卓开发--Activity
人生各自精彩
Andriod组件
Andriod系统中存在四大组件,四大组件是Android程序调用的基本模块。
Activity
- Android程序的呈现层,显示可视化的用户界面,接受与用户交互所产生的界面事件。
- Android应用程序可以包含一个或多个Activity,一般需要指定一个程序启动时显示的Activity。
Service
- Service一般用于没有用户界面但需要长时间在后台运行的应用。
- 可公开Service的程序接口供其他进程调用。
BroadcaseReceiver
- 用来接收广播消息的组件,不包含任何用户界面。
- 可以启动Activity或者Notification通知用户收到的重要信息。
Notification能够通过多种方法提示用户,包括闪动背景、震动设备、发出声音或在状态栏上放置一个图标
ContentProvider
- 是Android系统提供的一种标准的共享数据的机制,其他程序通过ContentProvider访问程序的私有数据。
- Andriod系统内部提供一些内置的ContentProvider,能够为应用程序提供重要数据信息,如:联系人,通话记录。
Activity
Activity是Andriod组件中最基本也是最常用的组件。Activity用于提供可视化用户界面的组件,它为用户提供了一个完成操作指令的窗口,可以与用户交互来完成某项内容。
在Android应用中,一个Activity通常解释一个单独的屏幕,它上面可以显示一些控件同时监听并处理用户事件做出响应。
新建Activity
图形化创建
包名处点击右键,选择New -> Activity -> [合适的Activity]
Android现在有很多不同内置Activity,帮助你的程序快速成型:
手动创建
创建Java/Kotlin类文件
在一个新的项目中,通常有一个初始化的HelloWorld页面,接下来我们在此基础上创建一个二级页面。
在新建的类中继承 AppCompatActivity
:
1 |
|
创建Activity的布局XML文件
即可快捷创建一个空的xml布局文件:
在AndroidManifest.xml文件中注册Activity
所有的Activity都必须在 AndroidMainfest.xml
文件中注册,否则系统无法启动它。
我们打开 app/manifests/AndroidManifest.xml
,在 <application>
标签内,添加一个新的 <activity>
标签来注册您的Activity。
1 |
|
android:name中需要设置为您的Activity的完整包名和类名,如果你的类文件在主包名下,可以使用 .
简写,例如 .SecondaryActivity
。
Activity的生命周期
Android开发指南中对于生命周期的讲解:activity 生命周期 | App architecture | Android Developers
工作流程
在Android系统中会维持一个Activity栈,当一个新的Activity创建时,它就会放到栈顶,这个Activity就处于运行状态。当再有一个新的Activity被创建后,会重新压入栈顶,而之前的Activity则会在这个新的Activity底下,同时进入后台。
四个状态
Active/Running运行状态:
- 一个新的Activity启动入栈后,它显示在屏幕最前端,处于站的最顶端(Activity栈顶),此时它处于可见并和用户交互的激活状态,叫做火种状态或运行状态。
paused暂停状态:
- 当Activity失去焦点,被一个新的非全屏的Activity或者一个透明的Activity被放置在栈顶,此时的状态叫做暂停状态(paused)。此时它依然与窗口管理器保持连接,Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),除非在系统内存极端低下时会被强行终止。所以它仍然可见,但已经失去焦点故不可与用户进行交互。
stopped停止状态:
- 如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(stopped)。它依然保持所有的状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,stopped的Activity被强行终止。
killed销毁状态:
如果一个Activity时paused或者stopped状态,系统可以将该Activity从内存中删除,Andriod系统采用的两种方式进行删除
- 要求该Activity结束(会调用
onDestroy()
方法)) - 直接终止它的进程(结束时不会执行
onDestroy()
)
当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。
- 要求该Activity结束(会调用
对于进入pause和stop状态的Activity,开发者需要自己在回调函数
onPause()
和onStop()
中自行决定释放哪些资源,暂停哪些工作。Android系统只保证:
- Activity 失去焦点和可见性
- 调用生命周期回调
系统不会自动暂停你代码中启动的资源和线程。
三个生命周期
Activity的生命周期可以分为全生命周期、可视生命周期和活动生命周期。每种生命周期中包含不同的事件回调函数。
全生命周期:
- 从
onCreate()
开始到onDestroy()
结束。Activity在onCreate()
设置所有的”全局”状态,在onDestroy()
释放所有的资源。
可视生命周期:
- 从
onStart()
开始到onStop()
结束。这段时间,可以看到Activity在屏幕上,尽管有可能不是焦点,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等。
活动生命周期:
- 从
onResume()
开始到onPause()
结束。在这段时间,该Activity处于所有Activity的最前面,和用户进行交互。Activity可以经常在Resume和Pause状态之间切换。所以在这些接口方法中的代码应该属于非常轻量级的。
回调方法详解
onCreate:
- 当Activity第一次创建时被调用。是生命周期开始的第一个方法。
- 工作:
- 调用setContentView方法加载页面
- 绑定布局控件
- 初始化数据
- Activity状态:被创建、不可见、不可交互
- 下一方法:onStart()
onStart:
- 当Activity正在变为可见时调用。
- 工作:
- 界面相关的初始化
- 启动界面可见时的运行逻辑
- Activity状态:可见,但还没有进入前台、不可交互
- 下一方法:onResume()
onResume:
- 当Activity可以跟用户交互时调用。
- 工作:
- 启动需要前台运行的功能
- 每次返回前台都会调用
- Activity状态:处于栈顶顶部,可交互,用户的焦点
- 下一方法:失去焦点时->onPause()
onPause:
- 当Activity暂停时调用这个方法。
- 工作:
- 暂停不必要的操作:动画、相机、传感器
- 释放轻量资源
- Activity状态:失去焦点,仍部分可见
- 下一方法:
- 重新获得焦点->onResume()
- 完全不可见->onStop()
onStop:
- 当Activity进入后台,且不会被用户看到时调用。
- 工作:
- 释放调整不再需要的资源(停止动画,降低定位精度)
- 保存持久化数据
- Activity状态:完全不可见
- 下一方法:
- 用户返回->onResart()->onStart()
- 如果结束->onDestroy()
onDestroy:
- 这个方法是Activity生命周期中调用的最后一个方法。会在Activity被销毁之前调用。
- 工作:
- 释放所有未释放的资源
- Activity:被彻底销毁
- 下一方法:生命周期结束。
onRestart:
- 这个方法是Activity处于停止状态后,又回到可视状态时调用,之后会调用
onResume()
。 - 工作:
- 恢复在onStop中释放的资源
- 重新初始化在后台被关闭的逻辑(注册监听器,刷新数据)
- Activity状态:不可见
- 下一方法:onRestart()
生命周期演示程序
为了方便我们最直观的感受到回调函数的触发时机以及触发顺序。这里设计了一个拥有三级页面的小型Demo。我们将主要观测二级页面即中间层页面的生命周期回调函数的触发情况。当回调函数被触发时,程序将发送系统通知,系统通知的内容为被调用的回调函数的名字。我们可以通过通知内容与顺序,掌握生命周期的触发时机以及顺序。
程序主要代码如下:
1 |
|
运行结果展示
从创建到可交互
从一级页面进入二级页面:
系统通知栏结果如下:
Android通知显示顺序为:新的消息在上,旧的消息在下。所以三条通知产生的顺序为:onCreate
->onStrart
->onResume
。
完全关闭页面
从二级页面返回一级页面:
二级窗口被完全关闭,调用三个生命周期,顺序分别为:onPause
->onStop
->onDestory
页面进入后台
从二级页面进入三级页面:
二级页面调用两个生命周期:onPause
->onStop
页面返回前台
从三级页面返回二级页面
调用三个生命周期:onRestart
->onStart
->onResume
不完全遮蔽页面
对三级页面进行修改,修改为一个弹窗,而非一个完整的页面,我们再次进行测试:
打开弹窗,只执行了onPause生命周期:
关闭弹窗,只执行了onResume生命周期:
四种启动模式
Standard
standard模式是Activity 的默认启动方式,每启动一个Activity就会在栈顶创建一个新的实例。
SingleTop模式
singleTop模式会判断要启动的Activity实例是否位于栈顶,如果位于栈顶则直接复用,否则创建新的实例。
SingleTask模式
singleTask模式下每次启动该Activity时,系统首先会检查栈中是否存在当前Activity实例,如果存在则直接使用,并把当前Activity之上的所有实例全部出栈。
SingleInstance模式
singleInstance模式会启动一个新的任务栈来管理Activity实例,无论从哪个任务栈中启动该Activity,该实例在整个系统中只有一个。
整个安卓系统中只存在一个该Activity实例。
使用场景:系统级的页面 :比如拨号界面、相机、播放器等,通常希望全局只有一个实例。