四種啟動模式的具體內(nèi)容大家可能都比較清楚了,但有些關于singleinstance啟動模式的場景卻有點不太清楚。我們都知道singleinstance模式的Activity會獨占一個TaskRecord,那由這個Activity再次去啟動其他Activity會怎么樣呢?本文不打算去詳細從源碼里探究了,只從現(xiàn)象來看結論。不太清楚具體啟動模式的同學請在網(wǎng)上自行查看?
場景一:MainActivity是standard模式,啟動了是singleinstance模式的SecondActivity,然后在SecondActivity中再次啟動MainActivity,此時會怎樣?點擊返回返回到哪兒呢?
show code:
//MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
}
//SecondActivity.java
public class SecondActivity extends Activity {
private final static String TAG = "spq";
private Button botton2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
botton2 = findViewById(R.id.button2);
botton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this,MainActivity.class);
startActivity(intent);
}
});
}
}
//AndroidManifest.xml
?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bjshipeiqing.testproject">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:launchMode="singleInstance"/>
</application>
</manifest>
代碼很簡單,這里只是給大家看下,下邊的場景不會再貼代碼,會把Activity的棧信息dump出來。
adb shell dumpsys activity activities
-
當我點擊了MainActivity以后,啟動了SecondActivity,此時的棧信息想必大家都已經(jīng)知道了,兩個TaskRecord,里邊分別放置了MainActivity和SecondActivity:
微信截圖_20190119131143.png - 當我點擊SecondActivity中的Button再次啟動一個MainActivity的時候,會發(fā)生什么呢?我們來看棧信息:

看出來了嗎?此時在MainActivity的TaskRecord中又啟動了一個MainActivity,而不是重新創(chuàng)建一個新的TaskRecord。
- 此時,我們點擊返回,大家猜測現(xiàn)在應該是哪個頁面呢?

應用界面的圖我就不貼了,從這里可以看出,由于剛才在MainActivity所在任務棧啟動了兩個MainActivity,此時返回,并不是返回到SecondActivity,而是返回到最初啟動的那個MainActivity,此時再點擊返回,我們肯定能猜到,此時是要返回到SecondActivity了:

結論:當一個Standard模式的Activity A啟動SingleInstance模式的Activity B后,會為B重新創(chuàng)建一個任務棧,此時,如果在B中再次啟動A,則會在A的任務棧中再啟動一個A,因為此時切回了A任務棧,所以再次點擊返回,返回的是第一次啟動的A,再返回,才會回到B。
場景二:如果MainActivity是standard模式,SecondActivity是singleinstance模式,ThirdActivity是標準模式,那么ThirdActivity,那么它會在哪個任務棧里邊呢?

可以看到,此時也會在MainActivity里創(chuàng)建ThirdActivity,并不會創(chuàng)建新的TaskRecord。想必此時點返回,大家也猜到應該會到哪兒了吧?沒錯,跟場景一是一樣的,返回了MainActivity,因為此時是在TaskRecord1的棧上:

此時,再次點擊返回,回到ThridActivity。
結論:singleinstance的Activity,啟動新的standard Activity時,并不會創(chuàng)建新的TaskRecord。
場景三:如果此時ThirdActivity是singTask模式,情況會怎么樣呢?
通過上述兩種場景,我們猜測,啟動的這個ThridActivity,也依然會被放到MainActivity的任務棧里,到底是不是這樣呢?我們來看實際情況:

可以看到,此時情況跟上述兩種情景是一樣,singleinstance的Activity,并不會為其創(chuàng)建新的taskRecord,而是在啟動該頁面的TaskRecord里繼續(xù)進行操作,后續(xù)的操作跟上述情景也是一樣的:

結論:singleinstance的Activity,啟動新的singleTask Activity時,并不會創(chuàng)建新的TaskRecord。
場景四:如果此時啟動的Activity為singleTop的呢?
想必驗證過了上述三種情景,結論大家一定很清楚了吧,直接來看圖:

結論:singleinstance的Activity,啟動新的singleTop Activity時,并不會創(chuàng)建新的TaskRecord。
總結
由于singleinstance啟動模式的Activity要獨占一個TaskRecord的特殊性, 不進行驗證不清楚它啟動下個Activity到底是怎么樣的,通過上述幾個小demo的驗證,我們可以知道:
- singleinstance啟動的Activity,再次啟動Activity,無論要啟動的Activity是何種啟動模式,都不會為其重新創(chuàng)建TaskRecord,而是在啟動它的Activity里按照以往的規(guī)律操作;
- Activity的回退操作是按整個TaskRecord來操作的,在上述情況下切了當前顯示的任務棧,那么回退將會按照該棧的壓入順利來進行,并不會嚴格按照我們操作的先后順序來執(zhí)行回退;
