Activity的启动模式分析

Android  2017年11月9日 pm7:36发布7年前 (2017)更新 城堡大人
111 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. 2024: bat脚本遍历(0条评论)
  2. 2022: Android 强制性横屏和设置系统横屏简介(0条评论)
  3. 2021: 一招永久去除WPS推送广告(0条评论)
  4. 2019: 大卫.索罗:孤独(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

洛夫:石榴树

假若把你的诺言刻在石榴树上枝桠上悬垂着的就显得更沉重了 我仰卧在树下,星子仰卧在叶丛中每一株树属于我,我在每一株树中它们存在,爱便不会把我遗弃 哦!石榴已成熟,这动人的炸裂每一颗都闪烁着光,闪烁着你的名字

MySQL忽略大小写简单记录

前言数据库查询时,在查询歌曲ID3信息时,由于存在歌曲名、艺术家或者专辑都存在英文字母,因此搜索时就存在大小写问题。本文简单记录一下查询数据库时忽略大小写遇到的问题。记录于此,方便自己查阅。正文隐藏内容!付费阅读后才能查看!¥1多个隐藏块只需支付一次付费阅读

git创建分支和提交分支

记录一下,以前不常用,以防出错在创建分支时,需要清除本地中的记录,比如新增,修改的文件,全部提交。git pull  同步到本地(下载)git push 同步到服务(提交)然后执行如下操作。一、git branch 查看当前分支二、git checkout -b xxx 创建xx...

[摘]Android性能优化篇之内存优化--内存泄漏

SHUI知道这篇文章对Android性能优化篇之内存优化--内存泄漏总结得很到位,基本上涵盖了。感谢感谢。什么是内存泄漏当一个对象已经不需要在使用了,本应该被回收,而另一个正在使用的对象持有它的引用,导致对象不能被回收。因为不能被及时回收的本该被回收的内存,就产生了内存泄漏。如果内存泄漏太多...

AsyncTask源码分析UML流程图

好早想学习画流程图,但一直拖着没有真正的画。最近分析了《AsyncTask源码分析》因此为这画了一个流程图,作为练习。图画得不是很好,主要是为了表达一下对AsyncTask的步骤理解。因为刚开始学画UML,有些细节没有把握好,望理解。谢谢 在SyncTask中,会调用两次PostR...

林语堂:人生就像一首诗

我想由生物学的观点看起来,人生读来几乎就像一首诗。它有其自己的韵律和拍子,也有其生长和腐坏的内在周期。它的开始就是天真烂漫的童年时期,接着便是粗拙的青春期,粗拙地企图去适应成熟的社会,具有青年的热情和愚憨,理想和野心;后来达到一个活动很剧烈的成年时期,由经验获得利益,又由社会及人类天性上得到更多的...