Activity的启动模式
来源:互联网 发布:国学软件哪个好啊 编辑:程序博客网 时间:2024/06/05 14:47
Activity的启动模式有4个,分别为standard、singleTop、singleTask、singleInstance。用户可以在AndroidManifest.xml中注册Activity时设置它的启动模式,例如:
<activity android:name=".A" android:launchMode="singleTask"/>
下面我们来一起看一下这四种启动模式
一、standard(标准启动模式)
这是Activity的标准启动模式,也是Activity的默认启动模式。在这种模式下,Activity可以被多次实例化,即在同一个任务栈中可以存在多个Activity实例,每个实例都会处理一个Intent对象。如果ActivityA的启动模式为standard。并且已经有一个ActivityA被启动,在该ActivityA中启动一个新的ActivityA实例。那么栈中会有2个ActivityA。
附上测试代码:
A.java
public class A extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); findViewById(R.id.a_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(A.this,A.class)); } }); }}
AndroidManifest.xml
<activity android:name=".A" android:taskAffinity="com.simple.myapplication.task1" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
执行 adb shell dumpsys activity 查看结果:
一开始只有一个ActivityA实例时: Stack #1: Task id #149 TaskRecord{1a7d0c7e #149 A=com.simple.myapplication.task1 U=0 sz=1} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000mp=com.simple.myapplication/.A } Hist #0: ActivityRecord{3933a57 u0 com.simple.myapplication/.A t149} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x1000000 cmp=com.simple.myapplication/.A } ProcessRecord{e66022c 13440:com.simple.myapplication/u0a57} Running activities (most recent first): TaskRecord{1a7d0c7e #149 A=com.simple.myapplication.task1 U=0 sz=1} Run #0: ActivityRecord{3933a57 u0 com.simple.myapplication/.A t149} mResumedActivity: ActivityRecord{3933a57 u0 com.simple.myapplication/.A t149}点击按钮继续启动一个ActiviyA 时: Stack #1: Task id #149 TaskRecord{1a7d0c7e #149 A=com.simple.myapplication.task1 U=0 sz=2} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000mp=com.simple.myapplication/.A } Hist #1: ActivityRecord{102084f5 u0 com.simple.myapplication/.A t149} Intent { cmp=com.simple.myapplication/.A } ProcessRecord{e66022c 13440:com.simple.myapplication/u0a57} Hist #0: ActivityRecord{3933a57 u0 com.simple.myapplication/.A t149} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x1000000 cmp=com.simple.myapplication/.A } ProcessRecord{e66022c 13440:com.simple.myapplication/u0a57} Running activities (most recent first): TaskRecord{1a7d0c7e #149 A=com.simple.myapplication.task1 U=0 sz=2} Run #1: ActivityRecord{102084f5 u0 com.simple.myapplication/.A t149} Run #0: ActivityRecord{3933a57 u0 com.simple.myapplication/.A t149} mResumedActivity: ActivityRecord{102084f5 u0 com.simple.myapplication/.A t149}
二、singleTop(栈顶复用模式)
如果有一个以singleTop模式启动的Activity的实例已经存在于任务的栈顶,那么在启动这个Activity时,不会创建实例,而是重用位于栈顶的那个实例,并且会调用该实例的OnNewIntent()方法。
附上测试代码:
B.java
public class B extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); //启动Activity A findViewById(R.id.b_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(B.this,A.class)); } }); }}
A.java
public class A extends AppCompatActivity { private static final String TAG = "A"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); //启动Activity A findViewById(R.id.a_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(A.this,A.class)); } }); Log.i(TAG, "onCreate: "); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.i(TAG, "onNewIntent: "); }}
AndroidManifest.xml
<activity android:name=".A" android:launchMode="singleTop" android:taskAffinity="com.simple.myapplication.task1" > </activity> <activity android:name=".B" android:taskAffinity="com.simple.myapplication.task1" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
测试结果:
第一步:栈中存在B、A时 Stack #1: Task id #151 TaskRecord{22b8911f #151 A=com.simple.myapplication.task1 U=0 sz=2} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000mp=com.simple.myapplication/.B bnds=[556,958][704,1142] (has extras) } Hist #1: ActivityRecord{2c7a4235 u0 com.simple.myapplication/.A t151} Intent { cmp=com.simple.myapplication/.A } ProcessRecord{21c76c6c 25188:com.simple.myapplication/u0a57} Hist #0: ActivityRecord{826ed5f u0 com.simple.myapplication/.B t151} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x1000000 cmp=com.simple.myapplication/.B bnds=[556,958][704,1142] (has extras) } ProcessRecord{21c76c6c 25188:com.simple.myapplication/u0a57} Running activities (most recent first): TaskRecord{22b8911f #151 A=com.simple.myapplication.task1 U=0 sz=2} Run #1: ActivityRecord{2c7a4235 u0 com.simple.myapplication/.A t151} Run #0: ActivityRecord{826ed5f u0 com.simple.myapplication/.B t151}第二步:点击A中的按钮,继续启动 ActivityA实例。 Stack #1: Task id #151 TaskRecord{22b8911f #151 A=com.simple.myapplication.task1 U=0 sz=2} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000mp=com.simple.myapplication/.B bnds=[556,958][704,1142] (has extras) } Hist #1: ActivityRecord{2c7a4235 u0 com.simple.myapplication/.A t151} Intent { cmp=com.simple.myapplication/.A } ProcessRecord{21c76c6c 25188:com.simple.myapplication/u0a57} Hist #0: ActivityRecord{826ed5f u0 com.simple.myapplication/.B t151} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x1000000 cmp=com.simple.myapplication/.B bnds=[556,958][704,1142] (has extras) } ProcessRecord{21c76c6c 25188:com.simple.myapplication/u0a57} Running activities (most recent first): TaskRecord{22b8911f #151 A=com.simple.myapplication.task1 U=0 sz=2} Run #1: ActivityRecord{2c7a4235 u0 com.simple.myapplication/.A t151} Run #0: ActivityRecord{826ed5f u0 com.simple.myapplication/.B t151} 可以发现栈中并无变化。 查看log信息: com.simple.myapplication I/A: onNewIntent: 执行了Activity A 的 OnNewInstance方法
三、singleTask(栈内复用模式)
如果一个Activity设置了该启动模式,那么一个任务栈中只能存在一个该Activity的实例。如果任务栈中存在该activity那么就不会创建新的activity,而是将这个已经存在的activity移至栈顶,并将位于该activity之上的别的activity销毁。并且和singleTop一样,会执行该activity的onNewIntent()函数。
附上测试代码:
public class A extends AppCompatActivity { private static final String TAG = "A"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); //启动Activity B findViewById(R.id.a_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(A.this,B.class)); } }); Log.i(TAG, "onCreate: "); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.i(TAG, "onNewIntent: "); }}
public class B extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); //启动Activity c findViewById(R.id.b_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(B.this,C.class)); } }); }}
public class B extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); //启动Activity c findViewById(R.id.b_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(B.this,C.class)); } }); }}
public class C extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_c); findViewById(R.id.c_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(C.this,A.class)); } }); }}
<activity android:name=".A" 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=".B" > </activity> <activity android:name=".C" > </activity>
测试流程: A启动B,B启动C ,C启动A 导致了BC出栈,最后栈中只剩下A,按返回键会返回桌面。
还有,假设现在存在2个栈,一个前台栈里面包含A,B和一个后台栈C,D
那么在B中启动D。将导致后台栈切换到前台。
另外我在测试中发现taskAffinity可以用来设置栈名称,一般情况下只有在启动模式为singleTask或者singleInstance和他配对使用时,启动的activity才会进入一个和这个名字相同的栈中。或者还有一种情况他会进入一个栈名称为taskAffiity设置的那个栈中,就是当启动他的activity的启动模式singleInstane时,他将创建一个栈名为taskAffinity的栈,用来压入新启动的activity。这是因为singleInstance的属性导致的他自身的栈中不能压入其他的Activity,所以会重新创建一个栈名为taskAffinity的栈用来存放启动的activity。
四、singleInstance(单实例模式)
这是一种加强的singleTask模式,它除了具有singleTask模式的属性外,还加强了一点,那就是该模式的Activity只能单独的位于一个任务栈中
附上测试代码:
public class A extends AppCompatActivity { private static final String TAG = "A"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); findViewById(R.id.a_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(A.this,B.class)); } }); Log.i(TAG, "onCreate: "); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.i(TAG, "onNewIntent: "); }}
public class B extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); findViewById(R.id.b_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(B.this,D.class)); } }); }}
<activity android:name=".A" android:taskAffinity="com.simple.myapplicaiton.task1" android:launchMode="standard" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".B" android:taskAffinity="com.simple.myapplicaiton.task1" android:launchMode="singleInstance" > </activity>
最终导致栈中的信息为:
Task id #238 TaskRecord{1ae14361 #238 A=com.simple.myapplicaiton.task1 U=0 sz=1} Intent { flg=0x10000000 cmp=com.simple.myapplication/.B } Hist #0: ActivityRecord{e8fbd4d u0 com.simple.myapplication/.B t238} Intent { flg=0x10000000 cmp=com.simple.myapplication/.B } ProcessRecord{12776e86 300:com.simple.myapplication/u0a57} Task id #237 TaskRecord{22b1347 #237 A=com.simple.myapplicaiton.task1 U=0 sz=1} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000cmp=com.simple.myapplication/.A } Hist #0: ActivityRecord{31785bab u0 com.simple.myapplication/.A t237} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.simple.myapplication/.A } ProcessRecord{12776e86 300:com.simple.myapplication/u0a57}可以发现存在2个栈
- activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity 的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- Activity的启动模式
- activity的启动模式
- Activity的启动模式
- JavaWEB之Filter的应用场景(2)
- 红黑树的插入与删除
- Android Dev Intro - Opengl ES 2.0 Render Stranges
- matlab图像处理基础知识2(matlab位运算操作)
- Android判断GPS是否开启和强制帮用户打开GPS
- Activity的启动模式
- Ti:事务的四大特性
- 理解PHP中的stdClass类
- Numpy之文件存取
- [EverString收录]综述 - 【Dr.Elephant源码分析系列文章-1】
- Elasticsearch ——ELK安装
- 用友通10.2标准版_100站点免狗补丁
- Java编程思想(第四版)笔记(二)
- java was started but returned exit code=13