Activity启动模式
来源:互联网 发布:中文域名转码 源码 编辑:程序博客网 时间:2024/06/06 09:10
一、启动模式简介
启动模式相当于Activity的一个属性,不同的启动模式Activity会有不同的行为表现,这里的行为主要体现在Activity的生命周期,特别是系统在启动多个Activity实例的时候,具体差异我们将用实例来说明。
二、任务栈简介
要了解Activity的启动模式,就不可避免地涉及到Activity所需的任务栈。什么是任务栈呢?android系统每启动一个新的Activity,都要将该Activity实例放入特定的任务栈,而这个任务栈和一个参数TaskAffinity有关,这个产生标识了Activity所需的任务栈的名字,默认的值为应用的包名。值得注意的是,TaskAffinity属性主要和singleTask启动模式(下面将要介绍)或allowTaskReparenting属性配合使用,在其他情况下没有意义。
既然叫“栈”,那么就符合“后进先出”的特点,我们每按一下back键,就有一个Activity实例出栈。
三、Activity启动模式
1、standard
标准模式,这是系统的默认模式。每次启动一个Activity都会重新创建一个Activity实例,不管这个Activity的实例是否存在。
2、singleTop
栈顶复用模式。在这种模式下,如果有Activity实例位于任务栈顶,那么就不会重新创建Activity实例,同时,Activity的onNewIntent方法会被回调。
3、singleTask
栈内复用模式。类似于单例模式,只要任务栈中有一个此Activity的实例,那么重新启动Activity就不会创建新的实例,而且和singleTop一样,onNewIntent方法会被回调
4、singleInstance
单实例模式,这是一种加强的singleTask模式,只要有一个任务栈中有Activity的实例,那么新实例就不会被创建。换句话说,singleInstance的Activity实例只能位于一个任务栈中。
下面我将用运行实例代码结合日志输出来分析各种启动模式的区别
代码:
LaunchMode应用:
package com.android.yanghuaan.launchmode;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class AActivity extends AppCompatActivity { private static final String TAG = "Activity_A"; @Override protected void onRestart() { Log.d(TAG, "restarted."); super.onRestart(); } @Override protected void onStart() { Log.d(TAG, "started."); super.onStart(); } @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "created."); super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); findViewById(R.id.start_B_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), BActivity.class); startActivity(intent); } }); findViewById(R.id.start_A_self_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), AActivity.class); startActivity(intent); } }); } @Override protected void onNewIntent(Intent intent) { Log.d(TAG, "new intent"); super.onNewIntent(intent); } @Override protected void onResume() { Log.d(TAG, "resumed."); super.onResume(); } @Override protected void onDestroy() { Log.d(TAG, "destroyed."); super.onDestroy(); }}
package com.android.yanghuaan.launchmode;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class BActivity extends AppCompatActivity { private static final String TAG = "Activity_B"; @Override protected void onRestart() { Log.d(TAG, "restarted."); super.onRestart(); } @Override protected void onStart() { Log.d(TAG, "started."); super.onStart(); } @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "created."); super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); findViewById(R.id.start_A_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), AActivity.class); startActivity(intent); } }); findViewById(R.id.start_B_self_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), BActivity.class); startActivity(intent); } }); } @Override protected void onResume() { Log.d(TAG, "resumed."); super.onResume(); } @Override protected void onDestroy() { Log.d(TAG, "destroyed."); super.onDestroy(); }}
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.yanghuaan.launchmode"> <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/AppTheme"> <!--主要在activity中改变启动模式,不同启动模式下此处代码不同--> <activity android:name=".AActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".BActivity"> </activity> </application></manifest>
LaunchMode应用包含两个Activity–A和B,每个Activity都有两个按钮,一个用来启动自己,另一个用来启动另一个Activity。
LaunchMode2代码:
package com.android.yanghuaan.launchmode2;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.start_other_activity_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClassName("com.android.yanghuaan.launchmode", "com.android.yanghuaan.launchmode.AActivity"); startActivity(intent); } }); }}
LaunchMode2应用包含一个Activity,它可以用来启动LaunchMode应用的一个Activity。只有在singleInstance的例子中才使用到LaunchMode2应用,因此写好只需跑一次、将LaunchMode2安装到安卓手机上即可。
通过在Activity的生命周期方法中添加输出日志的代码来追踪每个Activity的活动
standard 模式
<activity android:name=".AActivity" 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=".BActivity"> </activity>
操作步骤:
进入LaunchMode应用后点击两次启动自己的按钮
日志输出:
06-13 20:25:07.982 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:25:08.201 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:25:08.201 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:25:11.399 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:25:11.422 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:25:11.423 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:25:14.589 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:25:14.614 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:25:14.614 18980-18980/com.android.yanghuaan.launchmode D/Activity_A: resumed.
分析:
从日志可以看出,onCreate->onStart->onResume被被调用了3次,说明创建了3个AActivity的实例,即Activity实例被重复创建了。此时需要3次按back才能返回桌面
singleTop 模式
<activity android:name=".AActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".BActivity" android:launchMode="singleTop"> </activity>
操作步骤:
进入LaunchMode应用后先按启动BActivity的按钮,此时进入了BActivity;再按启动AActivity的按钮,此时进入了AActivity;再按两次启动自己(AActivity)的按钮
日志输出:
06-13 20:35:07.446 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:35:07.483 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:35:07.483 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:35:10.828 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: created.06-13 20:35:10.860 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: started.06-13 20:35:10.860 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: resumed.06-13 20:35:12.033 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:35:12.068 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:35:12.068 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:35:16.913 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: new intent06-13 20:35:16.913 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:35:19.872 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: new intent06-13 20:35:19.873 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:35:24.084 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: restarted.06-13 20:35:24.084 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: started.06-13 20:35:24.084 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: resumed.06-13 20:35:24.394 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: destroyed.06-13 20:35:24.951 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: restarted.06-13 20:35:24.951 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:35:24.951 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:35:25.252 4080-4080/com.android.yanghuaan.launchmode D/Activity_B: destroyed.06-13 20:35:27.292 4080-4080/com.android.yanghuaan.launchmode D/Activity_A: destroyed.
分析:
从AActivity到BActivity,再启动AActivity,发现onCreate被调用,即表明AActivity实例被重新创建;根据栈的特点可知此时AActivity的实例并没有位于栈顶,所以AActivity实例被重新创建;
返回AActivity后,再次启动两次AActivity都发现只有onResume和onNewIntent被调用,可知AActivity的实例被重新使用,并没有创建新的实例,这两次创建Activity的过程中AActivity的实例都位于栈顶,所以没有重新创建。
此时连续按back键的效果是:BActivity->AActivity->桌面;
singleTask 模式
<activity android:name=".AActivity" 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=".BActivity"> </activity>
操作步骤:
进入LaunchMode应用,按启动BActivity的按钮启动BActivity,再按启动AActivity的按钮启动AActivity
日志输出:
06-13 21:21:09.731 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 21:21:09.760 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 21:21:09.760 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 21:21:12.204 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: restarted.06-13 21:21:12.204 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: started.06-13 21:21:12.204 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: resumed.06-13 21:21:13.889 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: new intent06-13 21:21:13.889 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: restarted.06-13 21:21:13.890 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 21:21:13.890 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: resumed.
分析:
从BActivity启动AActivity,发现onRestart被调用,同时onNewIntent也被调用,表明AActivity的实例并没有被重新创建;此时只需按一次back键就可以返回桌面,因为在从BActivity创建AActivity的过程中BActivity被出栈了。
singleInstance 模式
<activity android:name=".AActivity" android:launchMode="singleInstance" android:allowTaskReparenting="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".BActivity"> </activity>
操作步骤:
先启动应用LuanchMode,再按启动BActivity的按钮启动BActivity;然后通过 home键返回桌面,启动LaunchMode2应用,在里面按启动其他应用Activity的按钮启动AActivity;最后通过 home键返回桌面,启动LaunchMode应用
日志输出:
06-13 20:55:40.044 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: created.06-13 20:55:40.136 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:55:40.137 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:55:41.046 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: created.06-13 20:55:41.079 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: started.06-13 20:55:41.079 21024-21024/com.android.yanghuaan.launchmode D/Activity_B: resumed.06-13 20:55:49.998 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: new intent06-13 20:55:49.998 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: restarted.06-13 20:55:49.998 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:55:49.998 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: resumed.06-13 20:56:00.336 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: new intent06-13 20:56:00.336 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: restarted.06-13 20:56:00.337 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: started.06-13 20:56:00.337 21024-21024/com.android.yanghuaan.launchmode D/Activity_A: resumed.
分析:
从LaunchMode2启动AActivity,发现AActivity并没有被重新创建,而是调用了onNewIntent和onRestart,并且重新从桌面进入LaunchMode应用也是如此,看起来就像AActivity从一个任务栈中移动到另一个任务栈中,这充分说明了singleInstance模式的Activity只能存在于一个任务栈中。
- android Activity启动模式
- Android Activity启动模式
- activity启动模式详解
- Activity启动模式1
- activity的启动模式
- Activity有四种启动模式
- Activity启动模式
- activity启动模式分析
- Activity的启动模式
- Activity 启动模式
- Activity启动模式
- Activity的启动模式
- Activity 启动模式
- Activity启动模式总结
- Activity的启动模式
- Activity的启动模式
- Activity 启动模式
- Activity启动模式
- I Hate It(splay)
- 差分熵与Kullback–Leibler散度
- bootstrap小记
- 信号灯的使用,PV算法交替输出AABB
- 软件体系结构学习心得
- Activity启动模式
- 深入了解Java虚拟机中字段表集合,和在class中如何组织
- C\C++应用程序性能优化
- [Spark]Spark RDD 指南四 RDD操作
- SDUVJ开发实录(八):总结
- Linux----使用GDB调试多进程和多线程程序
- Windows平台下python2和3的兼容问题解决
- 进程 线程 协程 管程 纤程 概念对比理解
- 自我对Map的使用方法总结与归纳!