Android四大组件之Activity
定义
Activity是安卓系统中负责用户可视化界面交互的关键组件。我们可以通过集成Acitivty接口来实现自定义Acitivty,新增的Activity必须在AndroidManifest.xml文件中声明才能被安卓系统识别。简单的说,一个Activity就是一个屏幕或窗口。
配置文件声明
在AndroidManifest.xml的application标签下添加一个activity标签用来声明一个Activity
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
...
</application ... >
...
</manifest >
android:name
用来声明Activity的类名android:launchMode
用来声明Activity的启动模式,默认为standardintent-filter
标签用来指定Activity启动的意图action
标签用来指定Acitivty启动意图的动作category
标签用来指定Activity启动意图的类别,android.intent.category.LAUNCHER
是最高优先级别,一般用作主页
生命周期
当用户浏览、返回和退出应用时,当前应用的Activity实例会在自身不同生命周期的状态间切换,Activity类为每个生命周期提供了一个回调方法,用以知晓当前Activity处于什么状态,开发者可以在生命周期的回调方法中定义某个状态下所要执行的动作。完整的生命周期状态切换流程如下图:
onCreate():必须实现的回调,在系统首次创建该Activity时触发,需要在回调中触发基本的应用启动逻辑,且该逻辑在整个生命周期中只会出现一次。比如通过声明布局、初始化界面、声明成员变量等。
onStart():
onCreate()
方法执行完成之后,Activity会进入到Started
状态,并触发onStart()
回调。onStart()
调用使Activity对用户可见,但并不能进行交互,应用在此状态下会为Activity进入前台并支持交互做准备。onResume():
onStart()
方法执行完成后,Activity会进入Resumed
状态,并触发onResume()
回调。此时Activity来到前台并支持与用户交互,在整个交互过程中都会保持此状态,直到某些事件发生,让当前Activity失去焦点。例如接听电话、跳转到别的Activity或者设备灭屏。当前状态下可以触发需要在前台支持用户交互的任何功能。当Activity从Paused
状态恢复后也会调用onResume()回调,所以在当前回调中也可以初始化onPause()回调中释放的资源。onPause():当Activity失去焦点或者发生中断事件后,Activity会进入
Paused
状态,并触发onPause()
回调。onPause()
调用是用户将要离开当前Activity的第一个标志 ,此时可以停止在Activity不再位于前台无需运行的功能并释放资源。如果当前是多窗口模式,则可以在onStop()的时候再释放资源。onStop():当Activity对于用户已完全不可见时,会进入到
Stoped
状态,并触发onStop()
回调。例如,当跳转到新的Activity占满整个屏幕或者用户退出,都会触发该回调。我们可以在该回调方法中释放在Activity不可见状态下的无用资源。当前状态下,
Activity
对象会继续驻留在内存中:该对象将维护所有状态和成员信息,但不会附加到窗口管理器。Activity 恢复后,Activity 会重新调用这些信息。无需重新初始化Activity中的组件。系统还会追踪布局中每个View
对象的当前状态,比如用户在EditText
微件中输入文本,系统将保留文本内容,所以无需保存和恢复文本。当用户返回到当前Activity时,系统会调用
onRestart()
,然后进到Started
状态。onDestory():当Activity结束运行时,会进入到
Destroyed
状态,结束运行前会触发onDestroy()
回调,此时需要释放所有资源
保存和恢复实例状态
当 Activity 因系统限制而被销毁时,在进入Stoped
状态前会调用onSaveInstanceState()
方法将当前Activity中所有View对象的相关信息保存到Bindle对象中,例如EditText
中的文本。
我们可以通过替换Activity的onSaveInstanceState()
方法自定义保存需要恢复的信息,如果仍需要默认实现保存视图层次结构的状态,必须在当前回调接口中调用父类的onSaveInstanceState()
方法。
private static final String STATE_SCORE = "playerScore";
private static final String STATE_LEVEL = "playerLevel";
// ...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, currentScore);
savedInstanceState.putInt(STATE_LEVEL, currentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
在用户返回到当前Activity时,系统会使用保存的Bundle对象中的信息重新创建Activity实例。在onStart()
执行前,会调用onRestoreInstanceState()
方法恢复实例状态。
同样我们可以通过替换Activity的onRestoreInstanceState()
方法处理需要恢复的信息,同时调用父类onRestoreInstanceState()
方法默认实现恢复视图层次结构的状态。
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
currentScore = savedInstanceState.getInt(STATE_SCORE);
currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
启动模式
1.任务栈
- 任务栈用来存放用户开启的所有Activity
- 应用创建时系统会默认分配一个任务栈,存放主Activity
- 新创建的Activity会被压入任务栈栈顶,点击返回后栈顶Activity被弹出并销毁,新的栈顶元素获得焦点来到前台
- 同一个任务栈,不在栈顶的Activity都处于
Stoped
状态 - 通过Activity属性affinity可以知晓是否在同一个任务栈中
2.声明启动模式
静态方式:AndroidManifest.xml中声明
android:launchMode
用来声明Activity的启动模式,默认为standard动态方式:代码中使用Intent指定
Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.setClass(this, ExampleActivity.class); startActivity(intent);
3.模式详情
(1)静态方式
Standard
默认标准模式。每次启动该Activity时都会在Task中创建新的实例
SingleTop
栈顶复用模式。启动Activity时,如果当前任务的栈顶已存在该Activity的实例,则调用其onNewIntent()方法将intent传递给该Activity,复用当前栈顶Activity。
SingleTask
栈内复用模式。启动Activity时,如果当前任务中已存在该Activity实例,则将任务栈中该Activity以上的Activity全部弹出,该Activity作为栈顶元素获得焦点。同样调用其onNewIntent()方法传递intent。
SingleInstance
全局唯一模式。启动Activity时,会重新创建一个新的任务栈用来存放它,而且这个任务栈中只有这一个Activity实例,如果已经创建过目标实例,则直接复用,并将该任务栈设置为
Foreground
状态。
(2)动态方式
- Intent.FLAG_ACTIVITY_NEW_TASK
- Intent.FLAG_ACTIVITY_SINGLE_TOP
- Intent.FLAG_ACTIVITY_CLEAR_TOP