android的四種加載模式

在多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>

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

1、standard模式,標準模式,也就是默認模式,不需要在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實例的倒序依次出現,類似退棧的操作,而剛纔操作跳轉按鈕的過程是壓棧的操作。

2、singleTop模式,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加載模式,結果也是一樣。

3、singleTask模式,和後面的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實例。

4、singleInstance模式

將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實例。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章