Activity的四种加载模式
>standard 标准模式 默认加载模式
>singleTop Task顶单例模式
>singleTask Task内单例模式
>singleInstance 全局单例模式
Android采用Task来管理多个Activity,当我们启动一个应用时,Android会为之创建一个Task,然后启动这个Task的入口Activity。Android的Task是一个麻烦的概念,可以将其理解为Activity栈,Task以栈的方式来管理Activity。
一.standard
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
this.setContentView(ll);
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString() + "\n" + "TASK ID为:" + this.getTaskId());
Button btn = new Button(this);
btn.setText("启动standard模式");
ll.addView(tv);
ll.addView(btn);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
二singleTop
此种模式与standard的不同是,当目标Activity位于栈顶时,系统不会重新创建该Activity的实例,而是直接复用已有的Activity实例。
此种模式只需将AndroidManifest.xml
修改为:
<activity
android:name="com.example.standard.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
采用此种模式的Activity在Task中只有一个实例。
当系统要启动该中模式的Activity时,有三种情况
>如果要启动的Activity不存在,则创建之,并将其加到Task栈的栈顶
>如果要启动的Activity已经位于Task的栈顶,则与singleTop模式的行为相同
>如果要启动的Activity不是位于Task的栈顶,则系统会把它上面的Activity移除栈,那么它将位于栈顶
例子:
Mainifest.xml
<activity
android:name="com.example.singletasktest.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".secondTask"
android:label="@string/second"
android:launchMode="singleTask">
</activity>
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.setContentView(layout);
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString() + "\n"
+ "Task ID:" + this.getTaskId());
Button btn = new Button(this);
btn.setText("启动SecondActivity");
layout.addView(tv);
layout.addView(btn);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, secondTask.class);
startActivity(intent);
}
});
}
}
secondTask.java
public class secondTask extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
this.setContentView(layout);
TextView tv = new TextView(this);
tv.setText("Activity为:" + this.toString() + "\n" +
"Task ID为:" + this.getTaskId());
Button btn = new Button(this);
btn.setText("启动MainActivity");
layout.addView(tv);
layout.addView(btn);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(secondTask.this, MainActivity.class);
startActivity(intent);
}
});
}
}
当点击启动secondActivity时,此时栈内有两个Activity,从上到下依次是secondActivity->MainActivity,然后点击"启动MainActivity“时,从上到下一次是
MainActivity->secondActivity->MainActivity,当再次点击”启动secondActivity“时,系统将把最上面的那个MainActivity移除,secondActivity到了栈顶,然后此时栈里只有两个。
四.singleInstance
此种加载模式,系统保证无论从哪个Task中启动Activity,只会创建一个Activity实例,并会使用一个全新的Task栈来装在该Activity实例
当采用singleInstance模式启动目标Activity时,可分为以下两种情况
>如果将要启动的Activity不存在,系统会先创建一个全新的Task,再创建目标Activity实例,并将它加入新的Task栈顶
>如果将要启动的Activity已存在,无论它位于哪个应用中,无论它位于哪个Task中,系统会把该Activity所在的Task转到前台,从而使该Activity显示出来
需要指出的是:采用sinlgeInstance模式加载Activity总是位于Task栈顶,并且该Task中只有这一个Activity。
他和singleTask类似,不同点是singleInstance要求activity的实例不仅只有一个,并且整个task中只有一个activity实例,而singleTask所在的栈中允许存在其他activity的实例。
由此我们可以知道设置了singleInstance的activity也具有上面的特性,此外,启动的activity设置了singleInstance,那么无论被启动的activity有没有设置singleInstance,都无法获取返回值,可以验证一下,将HomeActivity的android:launchMode="singleInstance"