Android的Activity的四種載入模式解析
一.在android中有幾種啟動Activity的模式?
standard(預設):每次都會新建。(每個Task都可以有,且可以有多個例項)。
singleTop:當前例項如果在棧頂,就不可以新建例項。(每個Task都可以有,且可以有多個例項,在棧頂的時候可以復 用)
singleTask:新建一個Task,如果有其它Task包含此例項,就直接呼叫那個Task。(只存在一個Task中)
singleInstance:新建一個Task,且該Task中只有其一個例項。(只存在一個Task中,且此Task中只有此一個例項)
其次有必要先解釋下Task這個概念:Task就是棧的意思,一個android應用的建立,則建立了一個Task,當每建立一個activity的時候,就將activity壓入Task中。
設定的位置在AndroidManifest.xml檔案中activity元素的android:launchMode屬性:
接下來以Demo的形式分別解釋這四種模式:
standard:
再次我們定義一個類A,通過A->A,再返回的形式來展現。
package com.android.douf; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class LaunchModeActivity_A extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView textView = new TextView(this); textView.setText(this + ""); Button button = new Button(this); button.setText("go:"); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(LaunchModeActivity_A.this, LaunchModeActivity_A.class); startActivity(intent); } }); LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); layout.addView(textView); layout.addView(button); this.setContentView(layout); } }
通過結果我們可以看見當不斷點選按鈕生成的是不同的物件例項。再點選返回按鈕的時候,返回上一個物件例項。
其實這就相當於一個壓棧的過程。
singleTop:其實singleTop和standard的區別就在於其建立的例項是否在棧頂。
此時我們將剛才那個Demo的launchMode改成standard。
此時發現不管點選多少次按鈕,都是同一個例項。且當按back健的時候,退出程式了。原因很簡單,因為類LaunchModeActivity_A是在棧頂。
singleTask:
定義A類跳轉到B類,再定義一個B類跳轉到A類。其中設定A類的啟動方式為:singleTask。B類的啟動方式為:standard。
A類:
package com.android.douf;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class LaunchModeActivity_A extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText(this + "");
Button button = new Button(this);
button.setText("go:");
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(LaunchModeActivity_A.this, LaunchModeActivity_B.class);
startActivity(intent);
}
});
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(textView);
layout.addView(button);
this.setContentView(layout);
}
}
B類:
package com.android.douf;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class LaunchModeActivity_B extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button=new Button(this);
button.setText("go actA");
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent();
intent.setClass(LaunchModeActivity_B.this, LaunchModeActivity_A.class);
startActivity(intent);
}
});
LinearLayout layout=new LinearLayout(this);
layout.addView(button);
this.setContentView(layout);
}
}
結果會發現A跳轉到B,建立了一個新的例項,當B再跳轉到A時,仍然是剛才的例項。因為啟動A的方式是singleTask。A中包含了此例項,所以當再次啟動的時候intent會直接傳遞給這個已建立的例項物件。
singleInstance:在這個模式之下,activity獨享一個Task,此時一個Task只有一個activity。
仍然使用上面的A和B類,將A類的啟動模式改為standard,把B的啟動模式改為singleInstance。
當點選跳轉A到B,再從B跳轉到A,然後back的時候,一般情況下應該是跳到B介面,但是這次全是A介面,並且當B
跳轉到A得時候建立一個新的例項在另一個Task中,並非同一個Task,結果如下圖: