Activity系列讲解---Activity的四大启动模式
开发者有时会问:为什么要为Activity指定加载模式?加载模式有什么作用?在这里,我简单的介绍以下,鄙人的理解:
Android中主要采用Task来管理Activity,当我们启动一个应用时,Android就会为之创建一个Task;然而Android中并没有为Task提供API,我们可以把Task理解为Activity栈,Task以栈的形式管理Activity.
1.在AndroidManifest.xml中配置Activity时,可以指定android:launchModel属性,该属性用于配置Activity的加载模式。
- standard:标准模式,也是默认的加载模式。用此模式启动一个Activity时,Android会为Activity创建一个新的实例,添加到当前的Task中。
- singleTop:这种模式基本与standard模式相同,不同之处在于--->当要启动的的Activity已经位于Task的顶部时,系统不会重新创建Activity实例,而是复用当前Activity实例
- singleTask:A(如果要启动的Activity不存在,系统会创建一个Activity实例,并将其加入到Task栈顶),B(若存在,并且位于Task栈顶,此时与singleTop模式的行为一致),C(若存在,不位于Task栈顶,系统会将此Activity上的所有Activity实例移出Task,从而使得此Activity位于栈顶)
- singleInstance:A(如果要启动的Activity不存在,系统会创建一个新的Task,并创建一个Activity实例,并将其加入到Task栈顶),B(若存在,无论它位于哪个应用程序,哪个栈中,系统会将此Activity所在的Task栈转到前台,从而使得此Activity显示出来)
四大启动模式,只有singleInstance可能会重新创建一个全新的Task,拥有两个Task栈;其余的三种模式只有一个Task栈
2.启动模式可以在代码中启动,也可以在清单文件中设置
(1)代码中启动(借助Intent的flag属性)
(2)清单文件中配置
3.下面我写了一个Demo,两个Avrivity(A与B),每一个Activity里有一个TextView,两个Button
(1)AActivity.class
/** * Activity的四种启动方式: * standard:默认的模式,每次启动startActivity()方法都会新建一个Activity对象 * singTop:在当前任务栈中,判断栈顶是否为当前的Activity,如果是,直接使用;如果不是,再创建新的Activity,放入栈顶 * singleTask:在当前任务栈中,判断栈里是否存在Activity,如果不存在,创建一个新的Activity入栈;如果存在,会把该Activity之上的所有Activity清除出栈,显示当前Activity * singleInstance:新创建一个任务栈,放入新创建的Activity,该任务栈只允许存在一个Activity实例,如果已存在,那么切换到该任务栈。 * */ public class AActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); } //启动AActivity public void buttonOneClick(View view){ Intent intent = new Intent(this,AActivity.class); startActivity(intent); } //启动BActivity public void buttonTwoClick(View view){ Intent intent = new Intent(this,BActivity.class); startActivity(intent); } }
(2)BActivity.class
public class BActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); } //启动AActivity public void buttonOneClick(View view){ Intent intent = new Intent(this,AActivity.class); startActivity(intent); } //启动BActivity public void buttonTwoClick(View view){ Intent intent = new Intent(this,BActivity.class); startActivity(intent); } }
(3)activity_a.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_a" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.langdon.taiyang.androidtest.Intent.AActivity"> <TextView android:id="@+id/tv_activity_one" android:text="A-->Activity" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/bt_activity_one" android:layout_below="@+id/tv_activity_one" android:text="A--Activity" android:onClick="buttonOneClick" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/bt_activity_two" android:layout_below="@+id/bt_activity_one" android:text="B--Activity" android:onClick="buttonTwoClick" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
(4)activity_b.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_b" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.langdon.taiyang.androidtest.Intent.BActivity"> <TextView android:id="@+id/tv_activity_two" android:text="B-->Activity" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/bt_activity_three" android:layout_below="@+id/tv_activity_two" android:text="A--Activity" android:onClick="buttonOneClick" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/bt_activity_four" android:layout_below="@+id/bt_activity_three" android:text="B--Activity" android:onClick="buttonTwoClick" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
4.运行结果以及四种启动模式分析
从配置文件中可以看出AActivity没有设置launchMode属性,默认会启用standard启动模式,下面我们以图1分析启动模式
图1
(1)android:launchMode="standard"
当应用程序开启时,A(AActivity)入栈,在AActivity中点击B--Activity按钮,会重新创建BActivity实例,B(BActivity)入栈,同时跳转到BActivity中;
然后在BActivity中点击A--Activity按钮,A(AActivity)入栈,同时跳转到AActivity中.Task栈中的情况如图1所示。
(2)android:launchMode="singleTop"
当应用程序开启时,A(AActivity)入栈,在AActivity中点击B--Activity按钮,会重新创建BActivity实例,B(BActivity)入栈,同时跳转到BActivity中;
然后在BActivity中点击B--Activity按钮,此时BActivity实例位于Task栈顶,不会重新创建BActivity实例,B也不会入栈(即使点击多次B--Activity按钮);
然后在BActivity中点击A--Activity按钮,A(AActivity)入栈,同时跳转到AActivity中.Task栈中的情况如图1所示。
图2 |
------------------------------> |
图3 |
(3)android:launchMode="singleTask"
当应用程序开启时,A(AActivity)入栈,在AActivity中点击A--Activity按钮,会重新创建AActivity实例,A(AActivity)入栈,
然后在AActivity中点击B--Activity按钮,会重新创建BActivity实例,B(BActivity)入栈,
然后在BActivity中点击A--Activity按钮,A(AActivity)入栈,同时跳转到AActivity中.Task栈中的情况如图2所示。
再在AActivity中点击B--Activity按钮,系统会在Task栈中查找B,B存在且不在栈顶,系统会将B上的A移出Task栈,使得B位于栈的顶部。Task栈中的情况如图3所示,点击3次退出按钮,此程序会退出。
图4--A栈 |
--------> |
图5--B栈 |
----> |
图6 |
图6 |
------------> |
图 7 |
---> |
图8 |
(4)android:launchMode="singleInstance"-------A栈只能存放AActivity的实例,B栈只能存放BActivity的实例
当应用程序开启时,A(AActivity)入栈,在AActivity中点击A--Activity按钮,会重新创建AActivity实例,A(AActivity)入栈,如图4所示。
然后在AActivity中点击B--Activity按钮,会创建一个全新的Task栈,同时创建BActivity实例,B(BActivity)入B栈,此时B栈在前面,A栈在后边。如图6所示
然后在BActivity中点击A--Activity按钮,A(AActivity)入A栈,此时A栈在前面,B栈在后边,同时跳转到AActivity中.Task栈中的情况如图7所示。
再在AActivity中点击3次退出按钮,A会退出,如图8所示。在B栈中点击1次退出按钮,此程序会退出。