Standard标准模式
SingleTop栈顶复用模式
SingleTask栈内复用模式
SingleInstance单例模式
1. Standard模式,活动启动的默认模式。
每启动一个新活动,都会进入任务栈,且处于栈顶位置。
对于标准模式来说,不管该活动是否已经存在于任务栈中,每次启动都会新创建该活动的实例。
2. SingleTop模式
若活动处于栈顶,则直接使用,不会再新创建该活动的实例。
若活动不处于栈顶,还是会再次创建该活动的实例。
3. SingleTask模式
活动在整个应用程序的上下文中只有一个实例。
每次启动任务,都会在任务栈中检查该活动的实例是否存在,
若存在,则直接使用该实例,并把其上所有的活动统统出栈;
若不存在,则重新创建该活动的实例。
4. SingleInstance模式
前提:每个应用都有自己的任务栈,来存储、管理该应用的活动的实例。
现象:启动模式是单例模式时,会启动一个新的任务栈来管理这个活动。
作用:共享活动实例。若想该应用程序的某个活动和其他应用共享,即其他应用可以调用该应用的活动,就要使用单例模式。
示意:应用内有活动A(假定在任务栈S1中),单例模式启动了活动B(此时任务B则在一个新的任务栈中,假定在S2内),普通模式启动了活动C(活动C会在任务栈S1中,在活动A之上,处于栈顶)。
一路按back键返回,出现的顺序是C->A->B。按back键时,S1在S2之上,S1内依次为C、A,S2内为B。
当C出栈后,A位于栈顶,显示A,再按back键,A出栈,S1为空,显示S2栈内的活动,B出现,再按back键,退到待机界面
5. Activity的onNewIntent()方法的调用时机。以SingleTask为例
1).清单文件
<activity
android:name=".MainActivity" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"></activity>
2).MainActivity
public class MainActivity extends Activity {
private static final String TAG = "MainActivity lyl123";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "onCreate()");
processIntent();
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "onNewIntent()");
setIntent(intent);//must store the new intent unless getIntent() will return the old one
processIntent();
}
private void processIntent() {
Intent intent = getIntent();
Log.e(TAG, "intent = " + intent);
}
}
3).SecondeActivity
public class SecondActivity extends Activity {
private static final String TAG = "SecondActivity lyl123";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.e(TAG, "onCreate()");
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this, MainActivity.class);
Bundle bundle = new Bundle(1);
intent.putExtra("DATA", bundle);
startActivity(intent);
}
});
}
}
4).分析
当MainActivity第一次创建的时候,走onCreate()方法。此时MainActivity对应的任务栈已存在,其实例也已存在。
跳转到SecondActivity,点击back按钮,再次回到MainActivity,就会走onNewIntent()方法,此时要调用setIntent()方法,保存从SecondActivity传过来的intent,之后再调用getIntent()方法,才能获取正确的intent。
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "onNewIntent()");
setIntent(intent);//must store the new intent unless getIntent() will return the old one
processIntent();
}
当SecondActivity中点击back按钮时,后台运行的MainActivity有可能被杀掉,若被杀掉,则会重新调用MainActivity的onCreate()方法,故此时若要接收从SecondActivity传过来的intent,则要在onCreate()中调用 processIntent()方法了。
5).结果
01-01 08:27:45.064 5406 5406 E MainActivity lyl123: onCreate()
01-01 08:27:45.065 5406 5406 E MainActivity lyl123: intent = Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.lyl.singletask/.MainActivity }
01-01 08:27:45.467 5406 5406 E SecondActivity lyl123: onCreate()
01-01 08:27:49.709 5406 5406 E MainActivity lyl123: onNewIntent()
01-01 08:27:49.710 5406 5406 E MainActivity lyl123: intent = Intent { flg=0x10000000 cmp=com.lyl.singletask/.MainActivity (has extras) }
6).总结:
前提:ActivityA已经启动过,处于当前应用的Activity任务栈中
当ActivityA的LaunchMode为SingleTask,SingleInstance时,如果已经ActivityA已经在堆栈中,那么此时会调用onNewIntent()方法。
当ActivityA的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法。
当ActivityA的LaunchMode为Standard时,由于每次启动ActivityA都是启动新的实例,和原来启动的没关系,所以不会调用原来ActivityA的onNewIntent()方法
注意:若ActivityA不处于当前任务栈的栈顶,都有被后台杀死的可能,故在onCreate()方法中要对intent做相应的处理。
6. 参考:
Activity的onNewIntent()方法何时会被调用?
Android:onNewIntent()触发机制及注意事项