Activity的四種加載模式


在多Activity開發中,有可能是自己應用之間的Activity跳轉,也有可能夾帶其他應用的可復用的Activity,可能會希望跳轉到原來某個Activity實例,而不產生大量重復的Activity。這需要為Activity配置特定的加載模式,而不是使用默認的加載模式。

Activity有四種加載模式,分別為:

1、standard:標准模式(默認模式),一調用startActivity()方法就會產生一個新的實例。

2、singleTop:如果Activity實例位於棧頂,就不產生新的實例,直接使用棧頂的實例,否則,就會產生一個新的實例。

例如:現在Task棧元素為A-B-C-D(D在棧頂),這時候給D發一個啟動Intent,如果D是 “standard”模式的,則生成D的一個新實例,棧狀態為A-B-C-D-D。如果D是singleTop模式的話,則不會生成D的新實例,棧狀態仍為A-B-C-D。如果這時候給B發Intent的話,不管B的launchMode是“standard”還是“singleTop”,都會生成B的新實例,棧狀態變為A-B-C-D-B。

3、singleTask:每次調用都會使用這個實例,不會去產生新的實例了。

4、singleInstance:跟singleTask模式基本上是一樣,只有一個區別:在這個模式下的Activity實例與其他Activity處在不同的Task中,此實例所處的Task中只能有這個Activity實例,不能有其他的實例。

如何設置Activity的加載模式?

加載模式可以在清單文件AndroidManifest.xml中的<activity>的launchMode屬性進行配置。

<activity android:name="ActivityOne" android:label="@string/app_name" android:launchMode="standard">
</activity>

四種加載模式的區別(示例說明):

1standard模式,標准模式,也就是默認模式,不需要在launchMode屬性配置。

/** * 默認(standard)加載模式 * * @author Harvey */
public class ActivityOne extends Activity implements OnClickListener { private TextView textView;// 顯示文本
    private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityOne"); button.setOnClickListener(this); textView.setText(this + ""); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityOne.this, ActivityOne.class);// 跳轉
 startActivity(intent); } }

 清單文件如下:

<activity android:name="ActivityOne" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
</activity>

經過多次點擊按鈕后,發現每次在界面上顯示hash code值都不同,證明每次點擊按鈕都創建了該Activity的新實例。接着點擊返回鍵,可以看到是按照剛才創建Activity實例的倒序依次出現,類似退棧的操作,而剛才操作跳轉按鈕的過程是壓棧的操作。

2singleTop模式,singleTop和standard模式都會將Intent發送新的實例(而后兩種模式如果已經有了實例,就不會發送到新的實例)。不過,singleTop要求如果創建Intent的時候棧頂已經有要創建的Activity的實例,則將Intent發送給該實例,而不發送給新的實例。

/** * singleTop模式 * * @author Harvey */
public class ActivityOne extends Activity implements OnClickListener { private TextView textView;// 顯示文本
    private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityOne"); button.setOnClickListener(this); textView.setText(this + ""); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityOne.this, ActivityOne.class);// 跳轉
 startActivity(intent); } }

清單文件如下:

<activity android:name="ActivityOne" 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>

點擊Button按鈕數次后,發現都是相同的Activity實例,因為該實例在棧頂,所有不會創建新的實例。如果點擊返回鍵,將退出應用。singleTop模式,可用來解決棧頂多個重復相同的Activity的問題。

如果A-Activity跳轉到B-Activity,再跳轉到A-Activity,就和standard模式一樣了,在B-Activity跳轉到A-Activity的時候就會創建A-Activity的新實例,因為當時的棧頂不是A-Activity實例。

ActivityOne.java

/** * singleTop模式 * * @author Harvey */
public class ActivityOne extends Activity implements OnClickListener { private TextView textView;// 顯示文本
    private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityTwo"); button.setOnClickListener(this); textView.setText(this + ""); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityOne.this, ActivityTwo.class);// 跳轉
 startActivity(intent); } }

ActivityTwo.java

public class ActivityTwo extends Activity implements OnClickListener { private TextView textView;//顯示文本
    private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityOne"); button.setOnClickListener(this); textView.setText(this + ""); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityTwo.this, ActivityOne.class);//跳轉
 startActivity(intent); } }

清單文件如下:

<activity android:name="ActivityOne" 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 android:name="ActivityTwo" android:label="@string/app_name">
</activity>

ActivityOne使用singleTop加載模式,ActivityTwo使用默認(standard)加載模式。ActivityOne也是要生成新的實例的,如果把ActivityOne的加載模式改為standard加載模式,結果也是一樣。

3singleTask模式,和后面的singleInstance模式都是只創建一個實例的。

當Intent到來,需要創建singleTask模式Activity的時候,系統會檢查棧里面是否已經有該Activity的實例,如果有直接將Intent發送給它。

把上面singleTop的實例中的ActivityOne的launchMode改為singleTask,ActivityTwo不改動。

<activity android:name="ActivityOne" android:label="@string/app_name" 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="ActivityTwo" android:label="@string/app_name">
</activity>

多次跳轉之后,發現Task中始終只有一個ActivityOne實例。

4singleInstance模式

將ActivityOne的模式配置為standard模式,將ActivityTwo的模式配置為singleInstance模式。

ActivityOne.java

/** * singleInstance模式 * * @author Harvey */
public class ActivityOne extends Activity implements OnClickListener { private TextView textView;// 顯示文本
    private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityTwo"); button.setOnClickListener(this); textView.setText(this + "\n" + "task id:" + this.getTaskId()); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityOne.this, ActivityTwo.class);// 跳轉
 startActivity(intent); } }

ActivityTwo.java

public class ActivityTwo extends Activity implements OnClickListener { private TextView textView;// 顯示文本
    private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView); button = (Button) findViewById(R.id.button); button.setText("go to ActivityOne"); button.setOnClickListener(this); textView.setText(this + "\n" + "task id:" + this.getTaskId()); } @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(ActivityTwo.this, ActivityOne.class);// 跳轉
 startActivity(intent); } }

清單文件如下:

<activity android:name="ActivityOne" 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="ActivityTwo" android:label="@string/app_name" android:launchMode="singleInstance">
</activity>

經過多次的跳轉發現ActivityOne和ActivityTwo的task id不相同,表明兩個的Acitity不在同一個Task中。ActivityOne的hash code值在每次跳轉之后都不同,表明每次跳轉后都會創建一個新的ActivityOne實例,ActivityTwo的hash code值每次跳轉之后都相同,表明ActivityTwo所在的Task中只有一個ActivityTwo實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM