Activity的启动模式分析

Android 5年前 (2017) 125la.com站长
170 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默认启动模式是standard模式。
该模式下,不论该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种启动模式

广告也精彩
版权声明:125la.com站长 发表于 2017年11月9日 下午7:36。
转载请注明:Activity的启动模式分析 | 125啦读书导航

相关文章

广告也精彩

暂无评论

暂无评论...