Activity的启动模式分析

Android  2017年11月9日 pm7:36发布7年前 (2017)更新 91es.com站长
93 0 0

以下是主要的测试代码

package com.hi.hello;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class SecondActivity extends Activity {

	private String TAG = "tag";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_second);
		Log.d(TAG, "--------SecondActivity---onCreate-----------");
		findViewById(R.id.bt_click).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				startActivity(new Intent(SecondActivity.this,
						MainActivity.class));
			}
		});

		findViewById(R.id.bt_click_two).setOnClickListener(
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						startActivity(new Intent(SecondActivity.this,
								SecondActivity.class));
					}
				});
	}

	@Override
	protected void onNewIntent(Intent intent) {
		// TODO Auto-generated method stub
		super.onNewIntent(intent);

		Log.d(TAG, "--------SecondActivity---onNewIntent-----------");
	}

	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();

		Log.d(TAG, "-------SecondActivity----onRestart-----------");
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();

		Log.d(TAG, "--------SecondActivity---onStart-----------");
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		// 打印task id 和hashCode
		Log.d(TAG, "--------SecondActivity---onResume-----------task id:"
				+ getTaskId() + "-----hashcode:" + hashCode());
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub

		Log.d(TAG, "--------SecondActivity---onPause-----------");
		super.onPause();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();

		Log.d(TAG, "--------SecondActivity---onStop-----------");
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();

		Log.d(TAG, "-------SecondActivity----onDestroy-----------");
	}

}

Activity的启动模式在AndroidManifest,xml中中使用android:launchMode="xxxx"来配置的,
其中xxxx代表四种模式:standard,singleTop、singleTask,singleInstance模式。
在默认情况下,如果不使用launchMode来配置模式,那么Activity默认是standard模式。

一:standard

标准模式,也是Activity默认启动模式。
该模式下,不论该Activity的实例是否存在,每次启动Activity都会重新创建一个新的实例。
下面是打印的日志(SecondActivity的启动模式是standard,在SecondActivity界面2次启动SecondActivity自己的打印日志如下)
D/tag ( 2906): --------SecondActivity---onStop-----------
D/tag ( 2906): --------SecondActivity---onCreate-----------
D/tag ( 2906): --------SecondActivity---onStart-----------
D/tag ( 2906): --------SecondActivity---onResume-----------task id:8-----hashcode:1095904712
D/tag ( 2906): --------SecondActivity---onPause-----------
D/tag ( 2906): --------SecondActivity---onStop-----------
D/tag ( 2906): --------SecondActivity---onCreate-----------
D/tag ( 2906): --------SecondActivity---onStart-----------
D/tag ( 2906): --------SecondActivity---onResume-----------task id:8-----hashcode:1095950136

说明:
从以上日志中可以看出SecondActivity的taskId没变,但hashcode却变了,也就是新创建2个Activity实例。
也就证明“standard模式下,不论该Activity的实例是否存在,每次启动Activity都会重新创建一个新的实例”

二:singleTop

栈顶复用模式

在该模式下的任务栈内,如果Activity的实例已经位于栈顶,那么Activity不会被重新创建,通过onNewIntent()重新打开Activity;如果Activity的实例不在栈顶,那么Activity会被重新创建。
当Activity为singleTop模式是分为以下情况

  1. 如果Activity实例不存在,就创建一个新的Activity实例
  2.  如果Activity实例存在,但在于栈顶,则不会新创建Activity,而是通过onNewIntent()启动存在的实例
  3.  如果Activity实例存在,但不在栈顶(在站内),则创建一个新的Activity实例。

下面是打印的日志(SecondActivity的启动模式是singleTop )

日志一

SecondActivity在栈顶时

D/tag ( 3133): --------SecondActivity---onPause-----------
D/tag ( 3133): --------SecondActivity---onNewIntent-----------
D/tag ( 3133): --------SecondActivity---onResume-----------task id:9-----hashcode:1095875904

日志二

SecondActivity存在且不在栈顶时或者不存在时

D/tag ( 3133): --------SecondActivity---onCreate-----------
D/tag ( 3133): --------SecondActivity---onStart-----------
D/tag ( 3133): --------SecondActivity---onResume-----------task id:9-----hashcode:1095977008

说明:

通过日志一和日志二发现,hashcode不同(也就是不同实例)。当SecondActivity不在栈顶时,会重新创建一个新的实例;当SecondActivity在栈顶时,只是通过onNewIntent()启动SecondActivity,不会新创建实例。

三:singleTask

站内复用模式。

在该模式下的任务栈内,如果Activity的不存在,就会启动一个Activity实例;如果Activity的实例存在,那么会通过onNewIntent()再次启动Activity,并把该实例顶部的其他Activity实例全部移除。
当Activity为singleTask模式时,分如下情况说明

  1. 如果Activity实例不存在,就新创建一个实例;
  2. 如果Activity实例存在,但在于栈顶,就通过onNewIntent()启动存在的实例;
  3. 如果Activity实例存在,但在于站内(不在栈顶),就通过onNewIntent()启动Activity实例,同时把在于Activity实例之上的其他Activity实例全部抛出。
    总的来说 SingleTask模式的Activity在同一个task中只有一个实例。

下面是打印的日志(SecondActivity的启动模式是singleTask)

日志一

SecondActivity实例不存在时

D/tag ( 3267): --------SecondActivity---onCreate-----------
D/tag ( 3267): --------SecondActivity---onStart-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336

日志二

SecondActivity存在且在栈顶时(此时和singleTop一样,通过onNewIntent()启动)

D/tag ( 3267): --------SecondActivity---onPause-----------
D/tag ( 3267): --------SecondActivity---onNewIntent-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336

日志三

SecondActivity存在切在栈内时(此时也是通过onNewIntent()启动存在的实例,但会把该实例顶部的实例全部杀死,如日志中的MainActivity被杀死)

D/tag ( 3267): ---MainActivity-onPause-----------
D/tag ( 3267): --------SecondActivity---onNewIntent-----------
D/tag ( 3267): -------SecondActivity----onRestart-----------
D/tag ( 3267): --------SecondActivity---onStart-----------
D/tag ( 3267): --------SecondActivity---onResume-----------task id:11-----hashcode:1095632336
D/tag ( 3267): ---MainActivity-onStop-----------
D/tag ( 3267): ---MainActivity-onDestroy-----------

四:singleInstance

单实例模式(singleInstance)的Activity在整个系统里只有一个实例。
如果不存在启动时,系统会创建一个新的任务栈,并且这个任务栈只有一个Activity实例。
其他的特性和singleTask和singleTop类似,具体如下分析
下面是打印的日志(SecondActivity的启动模式是singleInstance)

日志一

SecondActivity不存在时,就会在新的task中新创建一个

D/tag ( 2025): ---MainActivity-onCreate-----------
D/tag ( 2025): ---MainActivity--onStart-----------
D/tag ( 2025): ---MainActivity--onResume-------------task id:7
D/tag ( 2025): ---MainActivity-onPause-----------
D/tag ( 2025): --------SecondActivity---onCreate-----------
D/tag ( 2025): --------SecondActivity---onStart-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320
D/tag ( 2025): ---MainActivity-onStop-----------

日志二

SecondActivity存在时且在栈内时,是通过onNewIntent()启动存在的实例,但不会杀死其他Activity实例(因为不在同一个任务栈中)

.......
D/tag ( 2025): ---MainActivity--onResume-------------task id:7
D/tag ( 2025): ---MainActivity-onPause-----------
D/tag ( 2025): --------SecondActivity---onNewIntent-----------
D/tag ( 2025): -------SecondActivity----onRestart-----------
D/tag ( 2025): --------SecondActivity---onStart-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320
D/tag ( 2025): ---MainActivity-onStop-----------

日志三

SecondActivity存在时且在栈顶时,是通过onNewIntent()启动存在的实例

D/tag ( 2025): --------SecondActivity---onPause-----------
D/tag ( 2025): --------SecondActivity---onNewIntent-----------
D/tag ( 2025): --------SecondActivity---onResume-----------task id:8-----hashcode:1091614320

本文参考于《彻底弄懂Activity四大启动模式》和《如何正确理解和使用 Activity的4种启动模式

 历史上的今天

  1. 2022: Android 强制性横屏和设置系统横屏简介(0条评论)
  2. 2021: 一招永久去除WPS推送广告(0条评论)
  3. 2019: 大卫.索罗:孤独(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

Vim替换命令

前言简单记录Vim替换命令正文利用:s命令可实现字符串的替换# 命令之间是没有间隔的,下面表示为了看的清晰:范围 s /old /new如果没有指明范围,就表示当前行:s/old/new:s/old/new/g [g 表示当前行匹配的全部替换]:,$s/old/new/g ...

柴静:真相常流失于涕泪交加中

一美国有一个著名的白宫记者,叫海伦.托马斯,逼问过9任总统,进攻性极强,后来白宫特别在新闻厅给她专门设了把椅子,上面用小铜牌刻着她名字,又用她的名字命名了一个奖项,盛誉极隆。她八十多岁的时候在书里回忆自己职业生涯,曾经感叹美国新闻业的萧条,说“不知畏惧,不带好恶地去报道,美国的新闻人忘了吗?”...

[摘]Android稳定性(二)bootup fail

前言之前我也有整理相关的,但没有摘抄的这篇文章那么详细,因此这里摘抄于此,方便自己查阅。本文摘抄,感谢作者分析。好记性不如烂笔头正文下面就简单介绍一下Android系统启动流程。BootLoader启动开机供电,硬件电路会产生一个确定的复位时序用于硬件启动顺序,直至最后CPU启动;C...

Android悬浮球

前言上次介绍过创建一个《1像素的悬浮窗口》,这里需要做一个跟魅族一样的悬浮球,部分代码套用之前的。设计悬浮球时考虑全屏和非全屏,以及导航栏在左侧或底部情况等,要不然拖动时存在抖动问题。正文直接入正文,上代码片段。隐藏内容!付费阅读后才能查看!¥3 ¥6多个隐藏块只需支付一次付费阅读...

陆文夫:脚步声

照理不应该被自己的脚步声吓住,因为在少年时我就在黑暗无人的旷野间听到过此种脚步。那时我住在江边的一个水陆码头上,那里没有学校,只有二里路外的村庄上有一位塾师在那里授馆,我只能去那里读书。那位塾师要求学生们苦读,即使不头悬梁、锥刺股,却也要“闻鸡起舞”,所谓闻鸡起舞就是在鸡鸣时分赶到学塾里去读早书。农...

Android状态栏之LabelView

前言LabelView是一个监听栈顶应用变化并应用的label(也就是应用名称)展示的View。一般在顶部状态栏中常用。封装在一起,这样只需要在xml中添加即可,简单方便,可移植。记录于此,方便自己查阅。正文涉及功能时时监听顶部Activity变化获取当前Activity的la...