1.幼年鳴人偷學禁術:影分身之術 standard
在遙遠的火影村,誕生了一個黃色頭髮的小寶寶,他的母親給他取名爲漩渦鳴人。
但自很多年前那個不平靜的夜晚之後,鳴人失去了自己的父母,他不知道爲什麼,也不知道爲什麼街坊鄰里都對他抱有異樣的目光,所有的鄰居看他就像看瘟神一樣。這雖然讓他內心很不平靜,但是生性樂觀的他還是頑強的活了下來。
在一個夜晚,調皮的鳴人來到了一片森林,在這裏他找到了一個卷軸。上面印着幾個大字:封印の書。
安耐不住好奇心,他打開卷軸匆匆一撇,只看到幾個字:影分身之術。
還沒等看完,突然在森林裏出現了無數的敵人,鳴人險之又險的逃出了敵人的追捕。
自此,一個傳奇開始了。
雖然鳴人的天賦平平,但是他有一個最大的優點就是查克拉量賊大!這也給他創造了使用影分身得天獨厚的機會。
之後鳴人一路逆襲,把影分身運用到了極致。
在第四戰場,鳴人甚至能夠通過影分身來釋放影分身。
自此一役,鳴人腦海裏突然多了一個名詞 standard模式影分身之術
Standard模式影分身之術:每當產生一個新的影分身,這個影分身都會加入隊伍中並且處於本體的前方(相較於後者爲本體),之後鳴人再或者不在這個隊伍都對這個隊伍沒影響,因爲影分身也可以產生新的影分身。這時候,如果要銷燬影分身,必須要從最前方的依次銷燬,查克拉歸還體內。
鳴人:???
好了正經說一下standar啓動模式:
standrad模式是Android的默認啓動模式,如果我們創建一個活動不對AndroidMainfest.xml的內容做任何改動,那麼該活動默認的就是該模式。
在該模式下,每當啓動一個新的活動,那麼它就會返回棧中入棧,並且處於棧頂的位置。每當啓動一個活動後都依次入棧,系統不會在乎這個活動是否已經存在過,每次啓動都會創建一個該活動新的實例。
原理示意圖如下:
所以按照該原理:生成活動的順序是1->2->3,銷燬活動的順序是 3->2->1
我們用代碼來做個試驗:
Intent intent=new Intent(MainActivity.this,MainActivity.class);
intent.getAction();
Log.d("naruto",this.toString());
startActivity(intent);
在這個模式下運行,連續點擊按鈕生成新的MainActivity。在Logcat下如下顯示:
2020-03-20 00:14:07.162 21603-21603/com.example.naruto D/naruto: com.example.naruto.MainActivity$1@951b93d
2020-03-20 00:14:11.588 21603-21603/com.example.naruto D/naruto: com.example.naruto.MainActivity$1@341efd5
2020-03-20 00:14:17.420 21603-21603/com.example.naruto D/naruto: com.example.naruto.MainActivity$1@61d0184
可以看到每次點擊都生成了一個相同的MainActivity入棧,生成的順序就是1->2->3
如果我們點擊back,會發現需要點擊三次back才能退出。這也和他的出棧順序是一致的,依次出棧棧頂位置的活動。
2.金色閃光の飛雷神之術:singleTask
每一個成功的男人背後都有一個更成功的老爹,作爲四代火影的他,因爲他獨有的招式飛雷神之術被火影村的村民稱爲金色閃光。
但是這個火影村當時爲了自己的孩子甘願犧牲了自己。
在那個夜晚,他遇到了戴面具的神祕人。
並與之展開了激烈的大戰。
這場戰鬥充滿亮點,讓我們來分析一下本場戰鬥。
1.首先 他本身就是一個活動,這個活動是singleTask啓動模式。
2.此時由於帶土能夠將攻擊無效化,所以他準備給以奇襲。
3.掏出自己的手裏劍 一個新活動
4.拋出這個手裏劍,將手裏劍這個活動入棧,此時手裏劍處於棧頂位置,優先攻擊宇智波帶土
5.在手裏劍穿過帶土觸發了帶土的攻擊實體化後,帶土即將碰觸到水門的那一刻
6.施展飛雷神之術!一個新的波風水門活動啓動,此時由於這個活動是singleTask模式,在這個棧內已經存在,所以再次創建該活動時,在這個活動之上的所有活動統統出棧!
7.水門再次處於棧頂!施展螺旋丸!
正經時間:
singleTask模式,每次啓動該活動的時候系統首先會在返回棧中檢查是否存在該活動的實例,如果發現已經存在則直接使用該實例,並把在這個活動上的所有活動統統出棧,如果沒有發現就會創建一個新的活動實例。
原理圖如下:
簡單的代碼示例:
由於不是默認模式,所以我們在創建活動的時候,需要到AndroidMainfest.xml中去修改LaunchMode
代碼如下:
android:launchMode="singleTask"
接下來我們要再去創建一個活動,然後重寫FirstActivity的onRestart()
方法和SecondActivity的onDestroy()
方法。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button Button=findViewById(R.id.button3);
Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
});
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("波風水門","onRestart");
}
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Button button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(Main2Activity.this,MainActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("手裏劍","onDestroy");
}
}
然後讓我們運行一下,先從1->2 在從2->1看看會發生什麼
首先由1施展手裏劍,啓動了活動2,接下來2使用手裏劍施展飛雷神之術
這下波風水門活動1再次出現了。
那麼在這裏我們觀察Logcat會發現什麼呢?
2020-03-20 01:10:43.043 22966-22966/com.example.naruto D/波風水門: onRestart
2020-03-20 01:10:43.436 22966-22966/com.example.naruto D/手裏劍: onDestroy
我們發現 當我們準備再次創建一個活動1時,發現在棧內存在一個活動波風水門,此時onRestart這個活動,然後在此之上的活動都將被銷燬,那麼手裏劍自然就被onDestroy了。
此時棧中只剩下了一個活動1,我們在點擊一次Back就可以返回了。
應用場景:singleTask適合作爲程序入口點。例如瀏覽器的主界面。不管從多少個應用啓動瀏覽器,只會啓動主界面一次,其餘情況都會走onNewIntent,並且會清空主界面上面的其他頁面。之前打開過的頁面,打開之前的頁面就ok,不再新建。
摘自:chun_soft
3.絕技·螺旋丸:singleTop
對於主角鳴人,大家是一路看着他從小丸子搓成了大丸子到後面的四喜丸子,紅燒丸子,三煎丸子…
呸呸呸
當鳴人搓每次搓丸子的時候都會說一句:らせんガン!
這就和我們在AndroidMainfest.xml中指定啓動模式以下,我們在文件內書寫以下代碼:
<activity
android:name=".MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android:launchMode="singleTop" 將啓動模式定義爲singleTop模式
然後這時候鳴人就可以搓丸子了
在這種狀態下,丸子處於棧頂,當我們繼續搓來保持這個丸子的時候,就是我們在創建一個同樣的活動來讓丸子仍然處於棧頂。讓我們來寫一下代碼:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button Button=findViewById(R.id.button3);
Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MainActivity.class);
startActivity(intent);
}
});
Log.d(TAG,"正在搓丸子");
}
}
運行一下:會發現不管我們點擊多少次按鈕,在Logcat只顯示了一次:
2020-03-20 01:33:10.848 23627-23627/com.example.naruto D/MainActivity: 正在搓丸子
這是因爲此時丸子一直是處於棧頂的,當我們點擊按鈕來搓丸子的時候,由於當前棧頂有一個丸子,所以我們仍然搓這個丸子。於是乎這個棧頂就被複用了。這個活動只有一個實例,我們點擊一次back就可以返回。
如果我們把這個丸子扔出去,在搓一個其他丸子,那麼當我們還想搓這個丸子的時候,由於現在手裏是其他丸子,所以我們還得把其他的丸子扔了在去搓丸子纔可以。
當活動處於singleTop模式,在啓動活動時如果發現返回棧的棧頂已經是該活動,則可以認爲直接使用它,不會再創建一個新的活動。但是當這個活動不處於棧頂,那麼還需要在重新創建一個新的活動壓入棧並置於棧頂位置。
原理圖如下:
應用場景:singleTop適合接收通知啓動的內容顯示頁面。例如,某個新聞客戶端的新聞內容頁面,如果收到10個新聞推送,每次都打開一個新聞內容頁面是很煩人的,從外界可能多次跳轉到一個界面。
摘自 chun_soft
4.尾獸·九尾:singleInstance
鳴人在小時候不知道的是,當初自己的父親和母親犧牲自己,將九尾放入他的體內,讓他成爲了九尾的人柱力。這也就是爲什麼村民們如此懼怕他。
九尾充滿着怨恨,企圖控制鳴人。
但是鳴人用自己的執著和樂觀感化了九尾,自此之後,鳴人和九尾並肩作戰。在後面甚至可以召喚出體外進行作戰。
這是爲什麼呢,其實是因爲鳴人懂得了singeleInstance模式。
這種模式的特點是:
該模式的活動會啓動一個新的返回棧來管理這個活動(如果singleTask模式指定了不同的taskAffinity,也會啓動一個新的返回棧)。
這種模式下的鳴人到底有啥厲害的呢?請仔細看這個例子。
在沒有這種模式下的鳴人,只能依靠螺旋丸等普通的技能,還遠遠不到開掛的地步。
鳴人這個活動啓動螺旋丸或者影分身是這樣的 鳴人->螺旋丸 。
但是!
此時此刻,鳴人擁有了九尾。
這種情況下
鳴人召喚了九尾
鳴人->九尾
九尾作爲一個獨立的個體,擁有強大的戰鬥力 甚至可以放尾獸玉這個BUG技能!
但是尾獸玉始終是屬於九尾的力量。
於是乎 九尾被放在了一個新的棧中 這個棧就叫九尾不能說的祕密
在這個棧中 九尾->尾獸玉
所以當處於singeleInstance模式下的鳴人,是這樣放技能的。
鳴人->九尾->尾獸玉->螺旋丸
在這種情況下 鳴人與螺旋丸在一個棧中,由於鳴人召喚了九尾,九尾和尾獸玉則在一個新的棧中。
那麼鳴人這時候要如何停止這個模式呢?
首先點一次back,鳴人收回了螺旋丸
由 4->1 因爲此時九尾和尾獸玉並不在這個棧中。
然後在點一次back,這時候鳴人在棧頂,就可以準備回收九尾了,於是乎九尾的棧就顯示出來了,棧頂還是尾獸玉呢
由1->3(3是2和3這個棧的棧頂)
在點一次back,尾獸回收了尾獸玉 由 3->2
在點一次back,鳴人回收了尾獸,新生成的棧消失了。2->1
再點一次back,鳴人結束了戰鬥。 np!!!
原理圖如下:
應用場景:singleInstance適合需要與程序分離開的頁面。例如鬧鈴提醒,將鬧鈴提醒與鬧鈴設置分離。
希望大家可以通過這幾個小例子理解安卓活動的啓動模式之間的區別,很少寫博客,寫的不是很好,希望見諒。
最後附上名場面:
一袋米要抗幾樓
一袋米要抗二樓
一袋米要我給多嘞
一袋米要有洗尼
口口有泥
誰給你的一袋米樓
辛辣填sei!!!!