Activity的启动模式分析

Android  2017年11月9日 pm7:36发布7年前 (2017)更新 91es.com站长
99 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、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

Windows 文本大文件查看工具glogg

前言工作中,测试部偶尔要煲机测试,然后会提供一大堆巨大的日志。工作中比较常用的是notepad++(个人偏爱),经常打开大份日志时就卡顿,如果要整体搜索那就更快,偶尔甚至直接崩溃。同事有推荐pycharm看,但我不太喜欢,最后遇到glogg,看打日志就好多了。正文对于打日志,还有一种方式就...

个人常用的ListView方法简介

前言项目中ListView还是比较常用的,ListView有些方法或者配置属性都是比较常用也比较容易忘记的。因此,今天抽空整(抄)理(袭)一下,以便查阅。PS: 现在RecyclerView比较多了好记性不如烂笔头正文停止滚动 private void stopListView...

梁文道:专心吃饭

我曾经在别处介绍过一个我最喜欢的书痴故事,关于匈牙利革命时期的一位贵族,他嗜书如狂到了一个程度,即使是在被推上断头台之际,仍然不忘用笔在书上划线做笔记。假如一个人爱书爱到了连死之将至也不为所动的地步,那书痴这个称号他就实在是当之无愧了。我再和大家介绍一位真正的美食家。他是一位二十世纪的日本大禅师,...

梁启超:学问之趣味

我是个主张趣味主义的人,倘若用化学划分“梁启超”这件东西,把里头所含一种元素名叫“趣味”的抽出来,只怕所剩下仅有个零了。我以为凡人必常常生活于趣味之中,生活才有价值。若哭丧着脸挨过几十年,那么,生命便成沙漠,要来何用?中国人见面最喜欢用的一句话:“近来作何消遣?”这句话我听着便讨厌。话里的意思,好像...

adb shell命令控制WIFI连接开启/关闭状态

1、确保机器已经root,使用adb root 试试此命令如果返回如下,就表示不能rootadb: unable to connect for root: no devices/emulators found在上面root后,可以执行如下命令开关WiFi2、打开WIFI指令adb shel...

余秀华 : 栀子花开

白成一场浩劫,芬芳成一种灾难那些隐匿的声音一层层推出来,一层层堆积,再散开是的,无话可说了白,不是一种色彩。而是一种姿态 每一年,如期而至的突兀:存在即为表达反正是绚烂,反正是到来反正是背负慢慢凋残的孤独:耀眼的孤独义无反顾的孤独 那些喷薄的力从何而来?它...