淘先锋技术网

首页 1 2 3 4 5 6 7

既然是安卓开发,我们就免不了和Activity打交道,因为它是前台的界面,也是android四大组件之一,那我们就来谈谈Activity的四种加载模式。

为什么要为Activity指定加载模式?

Android对Activity的管理,采用Task(即栈)来管理多个Activity,当我们启动一个应用时,Android就会为之创建了一个Task,然后启动这个应用的入口Activity。

Android的Task是一个有点麻烦的概念,因为Android并没有为Task提供API,因此开发者无法真正访问Task,只能调用Activity的getTaskId()方法来获取它所在的Task的ID。

事实上,我们可以把Task理解成Activity栈,Task以栈的样式来管理Activity,先启动的Activity被放在Task栈底,后启动的Activity被放在Task栈顶。

那么Activity的加载模式,就负责管理实例化,加载Activity的方式,并可以控制Activity与Task之间的加载关系。

先看看哪四种模式:

①standard —>默认(标准)

不管Activity实例是否存在,都会创建一个新的实例装入Task。

(每次通过这种模式来启动目标Activity时,android总会为目标Activity创建一个新的实例,并将该Activity添加到目前的Task栈中。

这种模式不会启动新的Task,新的Activity将被添加到原有的Task中)

例子:10个应用程序都要调用浏览器的应用,

那么你需要创建10个浏览器对象的Activity的对象吗?

②singleTop —>栈顶单例(栈顶不会出现相邻的相同activity实例)

被跳转的Activity位于Task顶部时:

不会创建新的实例,直接复用已有的Activity实例

被跳转的Activity不是位于顶部时:

创建一个新的实例,同standard模式相似

③singleTask —>栈内单例(在同一个Task内只有一个实例)

采用这种模式分三种情况:

a)如果将要启动的目标Activity不存在,系统将会创建目标Activity的实例,并将它加入Task栈顶。

b)如果将要启动的目标Activity已经位于Task栈顶,此时同singleTop模式

c)如果将要启动的目标Activity没有位于Task栈顶,系统将会把位于该Activity上面的所有Activity移除Task栈,从而使得目标Activity转入栈顶。

④singleInstance —->全局单例(会单独拥有一个栈)

采用这种模式启动目标Activity时,可分为如下两种情况:

a)如果将要启动的目标Activity不存在,系统会先创建一个全新的Task,在创建目标Activity的实例,并将它加入新的Task的栈顶。

b)如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,无论它位于哪个Task中,系统会把该Activity所在的Task转到前台,从而使用该Activity显示出来。

需要指出:采用单例模式加载Activity总是位于Task栈顶,

采用单例模式加载Activity所在Task只包含该Activity

那如何设置呢??

这些启动模式可以在功能清单文件AndroidManifest.xml中进行设置,中的launchMode属性。

af029804d28d45fa45b1984911879845.png

相关的代码中也有一些标志可以使用,比如我们想只启用一个实例,则可以使用 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT 标志,这个标志表示:如果这个activity已经启动了,就不产生新的activity,而只是把这个activity实例加到栈顶来就可以了。

Intent intent = new Intent(ReorderFour.this, ReorderTwo.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(intent);

核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

大家看这张图应该能够明白栈的含义(画的有点丑):

927ce0cbfc86323e6947616367861505.png

我在这里就简单做点示例:

public class AActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_a);

}

public void goAActivity(View view) {

Intent intent = new Intent(AActivity.this,BActivity.class);

}

}

activity_a.xml

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.briup.lauchmodetest.AActivity">

android:onClick="goAActivity"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="跳转到AActivity"/>

public class BActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_b);

}

public void goBActivity(View view) {

Intent intent = new Intent(BActivity.this,AActivity.class);

}

}

activity_b.xml

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.briup.lauchmodetest.AActivity">

android:onClick="goBActivity"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="跳转到BActivity"/>

①现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,都采用默认的加载模式,栈的情况是怎么样的呢

8c7e5f0c4a16f127a921843f297de0a7.png

②现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用栈顶单例加载模式,栈的情况是怎么样的呢

1d3b07f1573a8eb9ef6a9d637dda245c.png

③现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用栈内单例加载模式,栈的情况是怎么样的呢

7ce1dd49488776701d0ec91a63c51c30.png

④现在我们假设 A 跳到 B ,然后 B 跳到 B,再 B 跳到 A,B采用全局单例加载模式,栈的情况是怎么样的呢

fb65e7ffbd63957c6c82c3be3cf85c37.png

大家有没有理解呢,去试试吧,有什么不懂可以在下方提问或者和我一起探讨。