``
js
一、Activity生命周期
1.1 什么是Activity
Activity即活动,是Android四大组件之一,是用户可视化的界面,界面中放置各种UI组件给用户操作及展示信息。
1.2 Activity的四种状态
1、running:运行中,当前界面在屏幕中可见且可操作。
2、paused:暂停中,当前界面可见但不可操作,例如出现一个弹框让该界面其他操作不可用。
3、stopped:停止中,不可见,被另一个界面完全覆盖,例如按下了Home键。
4、killed:退出,界面完全销毁。
1.3 进程优先级
1、前台:相当于状态中的运行,界面可见可操作。
2、可见:相当于状态中的暂停,界面可见不可操作。
3、服务:提供服务。
4、后台:相当于状态中的停止,界面不可见。
5、空:Activiy被回收。
1.4 生命周期
我们这里直接以官网图片来看,后面根据图并结合代码来看:【官网图片】
我们先来对生命周期的每个阶段进行说明:
onCreate(): 在创建Activity时,我们必须实现该方法,他会在首次创建Activity时触发,此时Activity处于"已创建"。
onStart(): 执行完该方法后,Activity处于"可见"状态,即"已开始"
onResume(): 执行完该方法后,Activity处于"已恢复",可与用户进行交互。若没有其他操作界面会长时间处于该方法执行后的状态。
onPause(): 用户即将离开Activity时首先执行的方法。执行后Activity将处于"已暂停",不会在前台展示,但任然处于可见状态。当用户由该"已暂停"状态再次变为可操作的"已恢复"状态时会重新执行onResume().
onStop(): 若Activity即将不可见时执行的方法,之后Activity处于"已停止"。当用户由不可见变为可见可操作状态时,通过onRestart()回到onStart()再次执行。
onDestroy(): Activity销毁之前执行的方法,之后Activity处于"已销毁"。
系统终止进程的可能性 | 进程状态 | Activity 状态 |
---|---|---|
较小 | 前台(拥有或即将获得焦点) | 已创建|已开始|已恢复 |
较大 | 后台(失去焦点) | 已暂停 |
最大 | 后台(不可见) | 已停止 |
空 | 已销毁 |
1.5 代码实战
我们先创建一个Activity并重写上面的各个方法,通过日志的打印来跟踪。
java
package com.hczn.activitydemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 引入的布局资源
Log.i(TAG, "进入了MainActivity的onCreate方法");
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "进入了MainActivity的onStart方法");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "进入了MainActivity的onResume方法");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "进入了MainActivity的onReStart方法");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "进入了MainActivity的onPause方法");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "进入了MainActivity的onStop方法");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "进入了MainActivity的onDestroy方法");
}
}
我们启动App并观察下控制台打印内容:
shell
// ----- ① ------
// ...
I/MainActivity: 进入了MainActivity的onCreate方法
I/MainActivity: 进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
我们按下Home建并观察控制台:
shell
// ----- ① ------
// ...
I/MainActivity: 进入了MainActivity的onCreate方法
I/MainActivity: 进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
// ----- ② -----
I/MainActivity: 进入了MainActivity的onPause方法
// ...
I/MainActivity: 进入了MainActivity的onStop方法
我们再次进入App中,观察控制台:
shell
// ----- ① ------
// ...
I/MainActivity: 进入了MainActivity的onCreate方法
I/MainActivity: 进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
// ----- ② -----
I/MainActivity: 进入了MainActivity的onPause方法
// ...
I/MainActivity: 进入了MainActivity的onStop方法
// ----- ③ -----
I/MainActivity: 进入了MainActivity的onReStart方法
进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
通过点击返回按键关闭Activity,观察控制台:
shell
// ----- ① ------
// ...
I/MainActivity: 进入了MainActivity的onCreate方法
I/MainActivity: 进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
// ----- ② -----
I/MainActivity: 进入了MainActivity的onPause方法
// ...
I/MainActivity: 进入了MainActivity的onStop方法
// ----- ③ -----
I/MainActivity: 进入了MainActivity的onReStart方法
进入了MainActivity的onStart方法
进入了MainActivity的onResume方法
// ...
// ----- ④ -----
I/MainActivity: 进入了MainActivity的onPause方法
I/MainActivity: 进入了MainActivity的onStop方法
I/MainActivity: 进入了MainActivity的onDestroy方法
二、Android任务栈
2.1 说明
我们还是以官网的一张图来说明:
Android中的每个Activity任务是由一个栈来维护的,一开始为空,当我们打开App时,主界面就是第一个Activity,并加入到栈中且在栈顶。当由该Activity跳转到另一个Activity时,另一个Activity继续进入栈中;以此类推。当我们按下返回键时,处于栈顶的Activity出栈并销毁。直到退出App。
2.2 代码实战
在前面代码的基础上我们新建一个Activity并添加一个Activity跳转按钮。
activity_main.xml:
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/openOtherActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到另一个界面"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java:
java
// ...
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Button openOtherActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
openOtherActivity = findViewById(R.id.openOtherActivity);
}
@Override
protected void onStart() {
// ...
openOtherActivity.setOnClickListener(v -> startActivity(new Intent(this, MainActivity2.class)));
}
// ...
}
我们运行App,点击主界面会跳转到另一个界面,再次按下返回键,观察控制台:
shell
# 下面为点击跳转界面按钮的打印
# ...
I/MainActivity: 进入了MainActivity的onPause方法
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@87891e3
I/MainActivity2: 进入了MainActivity2的onCreate方法
I/MainActivity2: 进入了MainActivity2的onStart方法
I/MainActivity2: 进入了MainActivity2的onResume方法
# ...
I/MainActivity: 进入了MainActivity的onStop方法
# 下面为按下返回按键的打印
I/MainActivity2: 进入了MainActivity2的onPause方法
I/MainActivity: 进入了MainActivity的onReStart方法
进入了MainActivity的onStart方法
I/MainActivity: 进入了MainActivity的onResume方法
# ...
I/MainActivity2: 进入了MainActivity2的onStop方法
I/MainActivity2: 进入了MainActivity2的onDestroy方法
三、Activity启动模式
3.1 standard(默认)
标准启动模式;每启动一个Activity都需要重新创建一个实例。
3.2 singleTop
栈顶复用模式;当启动的一个Activity实例和栈顶的Activity实例为同一个类型时,则不会重新创建。
3.3 singleTask
栈内复用模式;若任务栈中没有Activity实例则创建,若有该类型的Activity实例,则将该实例栈前面的Activity实例出栈,显示该Activity。
3.4 singleInstance
单例模式;同一类型的Activity只有一个实例,类似singleTask不过该Activity实例在另一个任务栈中。
3.5 代码实战
我们这里创建两个Activity,分别为ActivityA、ActivityB,在AndroidManifest.xml文件中通过android:launchMode="启动模式类型"
属性修改并结合控制台来观察。
1、AndroidManifest.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.hczn.activitydemo">
<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.ActivityDemo">
<!--<activity android:name=".ActivityA" android:launchMode="standard">--> <!--默认模式,可不设置-->
<!--<activity android:name=".ActivityA" android:launchMode="singleTop">-->
<activity android:name=".ActivityA" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ActivityC" />
<activity android:name=".ActivityB" />
<!--<activity android:name=".ActivityB" android:launchMode="singleInstance" />-->
<activity android:name=".MainActivity2" />
<activity android:name=".MainActivity">
</activity>
</application>
</manifest>
2、activity_a.xml
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=".ActivityA">
<TextView
android:id="@+id/showMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是ActivityA"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<Button
android:id="@+id/toActivityA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到ActivityA"
app:layout_constraintTop_toBottomOf="@id/showMessage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<Button
android:id="@+id/toActivityB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到ActivityB"
app:layout_constraintTop_toBottomOf="@id/toActivityA"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3、ActivityA.java
java
package com.hczn.activitydemo;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
public class ActivityA extends AppCompatActivity {
private static final String TAG = "ActivityA";
Button toActivityA;
Button toActivityB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
toActivityA = findViewById(R.id.toActivityA);
toActivityB = findViewById(R.id.toActivityB);
Log.i(TAG, "ActivityA.onCreate()...");
}
@Override
protected void onStart() {
super.onStart();
toActivityA.setOnClickListener(v -> startActivity(new Intent(this, ActivityA.class)));
toActivityB.setOnClickListener(v -> startActivity(new Intent(this, ActivityB.class)));
}
}
4、activity_b.xml
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=".ActivityB">
<TextView
android:id="@+id/showMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是ActivityB"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<Button
android:id="@+id/toActivityA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到ActivityA"
app:layout_constraintTop_toBottomOf="@id/showMessage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
5、ActivityB.java
java
package com.hczn.activitydemo;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
public class ActivityB extends AppCompatActivity {
private static final String TAG = "ActivityB";
Button toActivityA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
toActivityA = findViewById(R.id.toActivityA);
Log.i(TAG, "ActivityB.onCreate()...");
}
@Override
protected void onStart() {
super.onStart();
toActivityA.setOnClickListener(v -> startActivity(new Intent(this, ActivityA.class)));
}
}
6、操作说明
若ActivityA为standard模式,在ActivityA中每次点击跳转到ActivityA中都会执行一次ActivityA中的onCreate()
若ActivityA为singleTop模式,在ActivityA中点击跳转到ActivityA中不会执行ActivityA中的onCreated();若先跳转到ActivityB,从ActivityB再跳转到ActivityA,此时会执行ActivityA中的onCreate()
若ActivityA为singleTask模式,在ActivityA中点击跳转到ActivityA中不会执行ActivityA中的onCreated();若先跳转到ActivityB,从ActivityB再跳转到ActivityA也不会执行ActivityA中的onCreated();点击返回按键直接退出了App不会回到ActivityB
设ActivityA为默认模式,ActivityB为singleInstance模式,从ActivityA跳转到ActivityB中,点击Home键,再进入App中,发现我们看到的不是ActivityB(若为默认模式我们看到的应该是ActivityB)。我们再次点击ActivityA中的跳转到ActivityB,发现ActivityB中的onCreate()不会执行
四、Scheme跳转协议
后面有时间单开一篇来说明。非常重要。