activity有四种启动模式,熟悉启动模式可以帮我们更好使用activity。
模式设置两种方式:
first method,例如标准模式,Manifest 中:
activity中 android:launchMode=”standard”
second method,例如单例模式,activity中:
Intent i = new Intent(A.this,B.class);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
standard 标准模式:
系统默认模式,这种模式下,每次启动activity都会创建一个实例,
这种方式下,谁启动这个activity,这个activity就运行在启动它的activity所在的任务栈中。
比如,activity A 启动了activity B,那么standard模式下,B会在A所在栈的上面.
singleTop 栈顶复用模式:
这种模式下,如果新的activity位于栈顶,那么activity不会创建新的实例,它的onNewIntent方法会被回调,可以获取当前请求的信息,同时注意它的onCreate()、onStart()不会被调用;如果新的activity没有位于栈顶,activity会被重新创建。
singleTask 栈内复用模式:
这是单实例模式,只要activity存在栈中,那么多次启动activity不会重新创建,与singleTop情况一样,并且也会执行
onNewIntent方法。我的理解就是当前被调用的activity如果没有任务栈就会创建任务栈,把activity实例入栈;如果存在任务栈,栈内有实例的话,就把它置顶并且调用onNewIntent,与此同时,如果被调用的activity栈内实例上方有其他实例,则会移除其他实例;如果存在任务栈,但是没有实例的话,就会创建实例,并且压入栈内。
singleInstance 单实例模式,可以理解为singleTask的加强版,与singleTask都是单实例模式,但是区别是singleInstance是一个任务栈内只有一个实例。
举例说明:
新建3个activity,并设置launchMode(启动模式),进行压栈操作。
MainActivity:
MainActivity.java代码
package com.lcl.view;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("MM", "Main onCreate");
// Activity正在被创建;可以做初始化操作 。比如调用setContentView加载界面布局资源,
// 初始化Activity所需数据
}
@Override
protected void onRestart() {
super.onRestart();
Log.i("MM", "Main onRestart");
//Activity重新启动,Activity从不可见到可见,onRestart会被调用
}
@Override
protected void onStart() {
super.onStart();
Log.i("MM", "Main onStart");
//Activity正在被启动;此时,Activity可见,但是还没有出现在前台,无法和用户交互,可理解为用户不可见
}
@Override
protected void onResume() {
super.onResume();
Log.i("MM", "Main onResume");
//Activity已经可见,并且出现在前台并开始活动;与onStart()方法都表示Activity已经可见,
// 区别是onStart()是后台可见,onResume()是前台可见
}
@Override
protected void onPause() {
super.onPause();
Log.i("MM", "Main onPause");
//表示Activity正在停止,正常情况下,紧接着onStop会被执行
}
@Override
protected void onStop() {
super.onStop();
Log.i("MM", "Main onStop");
//Activity即将停止,可以做一些回收但不太耗时操作
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("MM", "Main onDestroy");
//表示Activity即将被销毁,此时可以做一些回收和资源释放操作
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String str = intent.getStringExtra("N");
Log.i("MM", "str:"+str);
}
public void onClick(View view){
Intent i = new Intent(MainActivity.this,Sec.class);
i.putExtra("save","dd");
startActivity(i);
}
}
activity_main.xml代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.lcl.view.MainActivity">
<TextView
android:background="#ff00ff"
android:padding="15dp"
android:textColor="#fff000"
android:layout_marginTop="30dp"
android:layout_marginLeft="20dp"
android:onClick="onClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Main->Sec!" />
RelativeLayout>
Sec.java代码:
package com.lcl.view;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
/**
* Created by liuchunliang on 2017/2/21.
*/
public class Sec extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sec);
Log.i("MM", "Sec onCreate");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i("MM", "Sec onRestart");
//Activity重新启动,Activity从不可见到可见,onRestart会被调用
}
@Override
protected void onStart() {
super.onStart();
Log.i("MM", "Sec onStart");
//Activity正在被启动;此时,Activity可见,但是还没有出现在前台,无法和用户交互,可理解为用户不可见
}
@Override
protected void onResume() {
super.onResume();
Log.i("MM", "Sec onResume");
//Activity已经可见,并且出现在前台并开始活动;与onStart()方法都表示Activity已经可见,
// 区别是onStart()是后台可见,onResume()是前台可见
}
@Override
protected void onPause() {
super.onPause();
Log.i("MM", "Sec onPause");
//表示Activity正在停止,正常情况下,紧接着onStop会被执行
}
@Override
protected void onStop() {
super.onStop();
Log.i("MM", "Sec onStop");
//Activity即将停止,可以做一些回收但不太耗时操作
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("MM", "Sec onDestroy");
//表示Activity即将被销毁,此时可以做一些回收和资源释放操作
}
public void onClick(View view){
Intent i = new Intent(Sec.this,Third.class);
startActivity(i);
}
}
sec.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:background="#ff00ff"
android:padding="15dp"
android:textColor="#fff000"
android:layout_marginTop="30dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Sec->Third!" />
LinearLayout>
Third.java
package com.lcl.view;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
/**
* Created by liuchunliang on 2017/2/21.
*/
public class Third extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
Log.i("MM", "Third onCreate");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i("MM", "Third onRestart");
//Activity重新启动,Activity从不可见到可见,onRestart会被调用
}
@Override
protected void onStart() {
super.onStart();
Log.i("MM", "Third onStart");
//Activity正在被启动;此时,Activity可见,但是还没有出现在前台,无法和用户交互,可理解为用户不可见
}
@Override
protected void onResume() {
super.onResume();
Log.i("MM", "Third onResume");
//Activity已经可见,并且出现在前台并开始活动;与onStart()方法都表示Activity已经可见,
// 区别是onStart()是后台可见,onResume()是前台可见
}
@Override
protected void onPause() {
super.onPause();
Log.i("MM", "Third onPause");
//表示Activity正在停止,正常情况下,紧接着onStop会被执行
}
@Override
protected void onStop() {
super.onStop();
Log.i("MM", "Third onStop");
//Activity即将停止,可以做一些回收但不太耗时操作
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("MM", "Third onDestroy");
//表示Activity即将被销毁,此时可以做一些回收和资源释放操作
}
public void onClick(View view){
Intent i = new Intent(Third.this,MainActivity.class);
i.putExtra("N","ddd");
startActivity(i);
}
}
third.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:background="#ff00ff"
android:padding="15dp"
android:textColor="#fff000"
android:layout_marginTop="30dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Third->Main" />
LinearLayout>
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lcl.view">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
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=".Sec"
android:configChanges="orientation|screenSize"
android:launchMode="standard" />
<activity
android:name=".Third"
android:configChanges="orientation|screenSize"
android:launchMode="standard" />
application>
manifest>
standard标准模式下,运行程序后生命周期:
Main进栈
此时,若是黑屏按电源键,后生命周期:
黑屏时程序此时会执行onPause 然后onStop到后台用户不可见(黑屏怎么可能看见原来的activity呢),再次按下电源键点亮后onRestart重启 启动 用户可见的过程。
按下Main->Sec 跳转按钮后:
跟预想的一样,先执行onPause 然后Sec 创建 启动 可见 最后MainActivity 执行onStop 用户不可见
Sec进栈
按下Sec->Third跳转按钮:
Third进栈
按下Third->Main跳转按钮:
虽然MainActivity之间创建过,但是在标准模式下,还是执行onCreate又创建了一遍,每次启动activity都会创建一个实例,
这种方式下,谁启动这个activity,这个activity就运行在启动它的activity所在的任务栈中。
此时任务栈为:
再说说singleTop 栈顶复用模式吧,
此时修改manifest文件,修改MainActivity的launchMode为singleTop:
android:launchMode="singleTop"
并且修改MainActivity 跳转:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String str = intent.getStringExtra("save");
Log.i("MM", "str:"+str);
}
public void onClick(View view){
Intent i = new Intent(MainActivity.this,MainActivity.class);
i.putExtra("save","kkk");
startActivity(i);
}
activity_main.xml:
TextView文字修改为:
android:text="Main->Main!"
修改完后重新运行程序:
执行了onNewIntent,先执行onPause然后onNewIntent最后用户可见。可以看得出来没有重新创建新的activity;如果activity没有在栈顶,那么它会创建一个新的实例,并压栈。
singleTask 栈内复用模式下,修改原来的文件:
manifest.xml中
MainActivity中
android:launchMode="singleTask"
MainActivity.java中
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String str = intent.getStringExtra("Save");
Log.i("MM", "str:"+str);
}
public void onClick(View view){
Intent i = new Intent(MainActivity.this,Sec.class);
i.putExtra("save","kkk");
startActivity(i);
}
activity_main.xml:
TextView文字修改为:
android:text="Main->Sec!"
此时,从Main点击跳转到Sec,再从Sec到Third,此时点击“Third->Main”按钮,显示周期:
Main->Sec->Third 栈内情况:
当我们执行“Third->Main”按钮点击操作栈内情况:
为什么会只剩下一个了呢?singleTask这种模式下,如果它上方有实力,则会移除实例,同时也会执行onNewIntent。
singleInstance单实例模式:这种方式下一个任务栈内只有一个实例,
把所有activity的launchMode 修改为singleInstance
android:launchMode="singleInstance"
再重新运行程序:
Main->Sec->Third任务栈情况:
可以看到建立3个任务栈,每个栈内有且只有一个实例,
当我们点击“Third->Main”按钮时:
同样的singleInstance也会执行onNewIntent方法,因为是独立栈所以会执行重启操作,不会创建新的实例。