第三期知识分享,介绍四大组件里的Activity相关
Activity
Activity是Context的子类
创建流程
创建Activity→创建布局→在Activity中加载布局→在AndroidManifest中注册Activity→设置主Activity
在Activity中加载布局
setContentView(R.layout.layout_name);
在AndroidManifest中注册Activity
<application ...> <activity android:name=".FirstActivity" android:label="An Activity"> </activity> </application>
设置主Activity
<application ...> <activity android:name=".FirstActivity" android:label="MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application>
android:label
标签同时也是启动器的名字
活动的生命周期
生命周期 | 介绍 |
---|---|
onStart | 可见;不在前台 |
onResume | 可见;在前台 |
onPause | 可见;不在前台 |
onStop | 不可见;不在前台 |
-
当活动在前台的时候处于
onResume
状态,此时启动新活动,如果新活动完全覆盖了旧活动,那么旧活动变为onPause
状态再变为onStop
状态;如果新活动没有完全覆盖旧活动(DialogActivity/透明主题),那么旧活动仅变为onPause
状态 -
当由活动A启动活动B(完全覆盖)时,生命周期时间顺序为
A:onPause
->B:onCreate
->B:onStart
->B:onResume
->A:onStop
,所以不要在onPause()中做耗时操作
-
活动在
onStop
状态时如果内存不足会被杀掉,如果此时又需要返回到该活动,那么从onCreate
开始启动 -
当手机屏幕旋转的时候,会发生运行时设备配置变更(如果没有特殊指定);Android会为新配置寻找最佳适配资源,所以活动也会经历一个销毁后重新创建的过程,临时数据若没有
onSaveInstanceState()
会被清除
状态保存
回调方法 | 描述 |
---|---|
onSaveInstanceState() | 在onStop()之前调用;Activity重建后,系统会调用onRestoreInstanceState() ,并把之前临时存储的Bundle对象同时传参给onRestoreInstanceState()和onCreate() |
onCreate() | 需要对Bundle对象进行非空判断 |
onRestoreInstanceState() | 在onStart()之后调用;只要进入该回调则说明Bundle对象非空,不需要非空判断 |
四种状态
状态 | 描述 |
---|---|
Running | 在前台 |
Paused | 失去焦点但仍然对用户可见 |
Stopped | 完全被另一个活动覆盖 |
Destroyed | 完全销毁 |
Task(任务栈)
你在最近任务列表里看到的就是task们
通过返回键退出当前APP的task后,在最近任务列表中还可以看到task残影,但是点击它则是重新启动APP
-
每个Activity都有taskAffinity,默认是Application的taskAffinity
-
Application的taskAffinity默认是包名
-
每个task的taskAffinity取自栈底Activity的taskAffinity
-
同一个taskAffinity可以被创建出多个task,但只会在最近任务列表中显示1个task
四种启动模式
在AndroidManifest文件中使用lunchMode属性
<activity android:name=".FirstActivity" android:launchMode="singleTop/singleTask/singleInstance"> ... </activity>
假设有应用X和应用Y
假设某Activity(A)属于应用X
standard
无论在哪个task中启动A,都会在启动A的那个task顶部创建A的1个实例
singleTop
启动时,如果当前task顶部已经是A,那么直接复用并执行onNewIntent()
,不会再onCreate()
singleTask
唯一性:只有其taskAffinity所指定的task含有A并且这个task里最多只有1个A
在【X的task】中启动A时
-
如果【X的task】中已经存在A,那么将A之上的Activity全部出栈,直接复用A并执行
onNewIntent()
,不会执行onCreate()
在【Y的task】中启动A时
-
如果【X的task】中已经存在A,那么将A之上的Activity全部出栈,直接复用A并执行
onNewIntent()
,不会执行onCreate()
随后【X的task】会叠加到【Y的task】上方(此时点击返回键,会一层一层先清空【X的task】,最终回到【Y的task】)
-
如果不存在【X的task】,那么新建【X的task】并放入A
Tips:如果在task叠加时点击○/□,叠加的task会由叠加关系转变为平行关系,所以如果此时再进入A所在的【X的task】,点击返回键,会一层一层先清空【X的task】,最终回到桌面
singleInstance
独占性:独占1个task
启动时,为A独立创造一个task(如果已经存在这样的task,那么直接复用并执行onNewIntent()
,不会再onCreate()
),随后叠加到当前task上方
如果在独占task里面再启动其他Activity,新的Activity会出现在另一个task里
活动的Flags
如果在Service/Application中启动Activity,这个Activity的task暂时还不存在,所以我们可以通过Intent的addFlags()临时设置Activity的启动模式
Flags | 描述 |
---|---|
FLAG_ACTIVITY_NEW_TASK | 其效果与指定singleTask模式一致 |
FLAG_ACTIVITY_SINGLE_TOP | 其效果与指定singleTop模式一致 |
FLAG_ACTIVITY_CLEAR_TOP | 当它启动时,在同一个task中位于它上面的Activity都要出栈(暂时不太理解这个的作用) |
活动的属性
返回栈属性
属性 | 作用 |
---|---|
allowTaskReparenting | 在Y中打开X的Activity,X的Activity先加进Y的task;但是用户一旦打开X,该Activity就会从Y的task中消失,移动到X的task里(Android 9/10 此属性无效) |
销毁属性
属性 | 作用 |
---|---|
clearTaskOnLaunch | 每次启动该活动时,在其之上的所有活动都会清除,保留自己 |
finishTaskOnLaunch | 当离开该活动再返回的时候,该活动会被finish,清除自己,保留其他活动 |
alwaysRemainTaskState | 始终保留自己 |
配置变更属性
属性 | 作用 |
---|---|
screenOrientation | 提前指定屏幕方向,在旋转设备时不会发生活动销毁重建 |
configChanges | 捕获运行时设备配置变更,当发生了所指定的事件时,活动只执行onConfigurationChanged()
|