一、Activity 的生命周期
Activity 的生命周期是 Activity 在整个运行过程中处于的状态的一个集合。当我们操作 app 与其它 app 进行交互时,Activity 就会进入不同的状态。如图
当由 Activity1 启动 Activity2 后,Activity1 就会停止活动,Activity2 开始活动。当 Activity2 返回时,Activity1 会继续活动,Activity2 会被销毁。
二、Activity 的状态
当 Activity 在运行或者退出时会有不同的生命周期状态,Android 在不同的阶段都会有不同的生命周期回调方法。我们可以在 Activity 类中去重写这些方法,来做到在不同的生命周期实现不同的行为。牢记一点,生命周期状态针对的是每个 Activity,而不是 app。如图
三、详细分析 Activity 的不同阶段
1)onCreate( )
当我们的 Activity 第一次启动时会进入进入创建状态。当 Activity 首次被创建时,系统会调用 onCreate( ) 方法来初始化这个 Activity。当然,Created 是一个转瞬即逝的状态,会在之后转换成 Started 状态。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... ...
}
2)onStart( )
当 Activity 被初始化之后,系统就会调用 onStart( ) 方法,但是此时虽然在屏幕上可见,但是此时用户是无法与其交互的,直到 onResume( ) 被调用。在 app 运行的过程中,Activity的 onStart( ) 方法可能会被多次调用,但是onCreate( ) 方法只会被调用一次。
通常,我们会将 onStart( ) 与 onStop( ) 对应,onStop( ) 会释放硬件资源,相反,onStart( ) 会注册这些资源。
与 onCreate( ) 同样的是,onStart( ) 也是一种转瞬即逝的状态,启动后,Activity会立即进入 onResume( ) 状态。
@Override
protected void onStart() {
super.onStart();
... ...
}
3)onResume( )
resume 恢复的含义,我们将这种状态称为恢复状态,通常也称为运行状态。onResume( ) 方法可能也会被多次调用,每次 app 从暂缓状态返回时。
与onStart( ) 相同的是,onResume( ) 与 onPause( ) 相对应,只要 Activity 能与用户进行交互,那么久说明 Activity 处于运行状态,从运行状态可以进入暂缓状态。
@Override
protected void onResume() {
super.onResume();
... ...
}
4)onPause( )
能够产生 onPause( ) 的几种情况:
1. 当 Activity 进入后台,但是还没有完全停止,表明用户正在离开你的 Activity。
2. 当前的 Activity 在屏幕上仅部分可见,可能是因为一个对话框或者透明的 Activity 覆盖在 当前 Activity 的顶部。
3. 在分屏模式下,Activity 显示在屏幕上,但是用户可能正聚焦在另一个 Activity上
onPause( ) 方法可以用来 暂停视频的播放、释放硬件密集型资源、提交未保存的 Activity 的更改。onPause( ) 方法应该快速执,不应该将该方法用于 CPU密集型操作,例如:将数据持久化到数据库。 我们应该知道,当 app 进入暂缓状态时,它仍可能在屏幕上可见,当执行 onPause( ) 时,任何延迟都影响用户到下一个 Activity。所以应当将 重负载操作 放到停止状态执行。
@Override
protected void onPause() {
super.onPause();
... ...
}
5)onStop( )
当一个 Activity 在屏幕上不可见时,那么这个 Activity 就处于停止状态。此时,Android 系统会将 Activity 的实例保留在 栈 中,如果用户返回,系统就会重新启动它,如果资源不足且用户未返回,则可能会完全终止这个 Activity。
活动停止时会调用 onStop( ) 方法。该方法保存持久化数据并释放 onPause( ) 未释放的数据。
@Override
protected void onStop() {
super.onStop();
... ...
}
6)onDestroy( )
当我们的 Activity 被销毁时,它将被彻底关闭,并且 Activity 的实例将被回收。使用 onDestroy( ) 会清理我们的 Activity,并确保在 Activity 被清理后,没有一个组件在运行。在某些情况下,系统可能只是会简单的终止进程 Activity,而不去调用此方法。所以我们不推荐用 onDestroy( ) 来保存数据或者 Activity 状态,而是用 onPause( ) 或者 onStop( ) 代替。
能够产生 onDestroy( ) 的几种情况:
1. 调用 finish( ) 方法手动关闭它
2. 回到上一个 Activity
3. 内存不足的情况下,系统会回收任何停止的 Activity,来释放资源
4. 发生设备更改时
@Override
protected void onDestroy() {
super.onDestroy();
... ...
}
7)onRestart( )
重新启动状态是一种转瞬即逝的状态,仅当停止的“活动”再次启动时才会发生。在 onStop( ) 和onStart( ) 之间调用 onRestart( ) 方法。
@Override
protected void onRestart() {
super.onRestart();
... ...
}
四、测试代码
Java文件
MainActivity类
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("现在的状态是", "onCreate()......");
}
public void toAnotherActivity(View view) {
Intent intent = new Intent(this, OtherActivity.class);
startActivity(intent);
}
@Override
protected void onStart() {
super.onStart();
Log.d("现在的状态是", "onStart()......");
}
@Override
protected void onStop() {
super.onStop();
Log.d("现在的状态是", "onStop()......");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("现在的状态是", "onDestroy()......");
}
@Override
protected void onPause() {
super.onPause();
Log.d("现在的状态是", "onPause()......");
}
@Override
protected void onResume() {
super.onResume();
Log.d("现在的状态是", "onResume()......");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("现在的状态是", "onRestart()......");
}
}
OtherActivity类
public class OtherActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
}
}
XML文件
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick="toAnotherActivity"
android:text="Click Me!"/>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_other.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".OtherActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.com.myactivitylifecycle">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyActivityLifeCycle">
<activity android:name=".OtherActivity"/>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
测试结果
① MainActivity启动时状态集
② MainActivity 跳转到 OtherActivity 后,MainActivity的状态集
③ 从 otherActivity 跳转回 MainActivity 后,MainActivity的状态集