activity启动模式探究
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代码:
<?xml version="1.0" encoding="utf-8"?><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
<?xml version="1.0" encoding="utf-8"?><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
<?xml version="1.0" encoding="utf-8"?><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:
<?xml version="1.0" encoding="utf-8"?><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方法,因为是独立栈所以会执行重启操作,不会创建新的实例。
更多相关文章
- No.11 使用firewall配置的防火墙策略的生效模式
- S5PV210 Android(安卓)DM9000驱动
- Android(安卓)开发之 Drawable系列
- android原生JSON解析实例
- Android(安卓)高级UI 目录
- android javascript 调用activity
- Android(安卓)源码分析-打电话和发短信
- Android仿硅谷商城实现购物车实例代码
- Android仿美团分类下拉菜单实例代码