Android+《火影忍者》活动启动模式以及应用场景的那些事

启动模式

  • 1.幼年鸣人偷学禁术:影分身之术 standard
  • 2.金色闪光の飞雷神之术:singleTask
  • 3.绝技·螺旋丸:singleTop
  • 4.尾兽·九尾:singleInstance

1.幼年鸣人偷学禁术:影分身之术 standard

在遥远的火影村,诞生了一个黄色头发的小宝宝,他的母亲给他取名为漩涡鸣人。
Android+《火影忍者》活动启动模式以及应用场景的那些事_第1张图片
但自很多年前那个不平静的夜晚之后,鸣人失去了自己的父母,他不知道为什么,也不知道为什么街坊邻里都对他抱有异样的目光,所有的邻居看他就像看瘟神一样。这虽然让他内心很不平静,但是生性乐观的他还是顽强的活了下来。

在一个夜晚,调皮的鸣人来到了一片森林,在这里他找到了一个卷轴。上面印着几个大字:封印の书。

安耐不住好奇心,他打开卷轴匆匆一撇,只看到几个字:影分身之术。
Android+《火影忍者》活动启动模式以及应用场景的那些事_第2张图片
还没等看完,突然在森林里出现了无数的敌人,鸣人险之又险的逃出了敌人的追捕。

自此,一个传奇开始了。

虽然鸣人的天赋平平,但是他有一个最大的优点就是查克拉量贼大!这也给他创造了使用影分身得天独厚的机会。

之后鸣人一路逆袭,把影分身运用到了极致。

在第四战场,鸣人甚至能够通过影分身来释放影分身。

自此一役,鸣人脑海里突然多了一个名词 standard模式影分身之术
Standard模式影分身之术:每当产生一个新的影分身,这个影分身都会加入队伍中并且处于本体的前方(相较于后者为本体),之后鸣人再或者不在这个队伍都对这个队伍没影响,因为影分身也可以产生新的影分身。这时候,如果要销毁影分身,必须要从最前方的依次销毁,查克拉归还体内。

Android+《火影忍者》活动启动模式以及应用场景的那些事_第3张图片
鸣人:???

好了正经说一下standar启动模式:

standrad模式是Android的默认启动模式,如果我们创建一个活动不对AndroidMainfest.xml的内容做任何改动,那么该活动默认的就是该模式。
在该模式下,每当启动一个新的活动,那么它就会返回栈中入栈,并且处于栈顶的位置。每当启动一个活动后都依次入栈,系统不会在乎这个活动是否已经存在过,每次启动都会创建一个该活动新的实例。

原理示意图如下:
Android+《火影忍者》活动启动模式以及应用场景的那些事_第4张图片

所以按照该原理:生成活动的顺序是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
Android+《火影忍者》活动启动模式以及应用场景的那些事_第5张图片

如果我们点击back,会发现需要点击三次back才能退出。这也和他的出栈顺序是一致的,依次出栈栈顶位置的活动。

2.金色闪光の飞雷神之术:singleTask

Android+《火影忍者》活动启动模式以及应用场景的那些事_第6张图片

每一个成功的男人背后都有一个更成功的老爹,作为四代火影的他,因为他独有的招式飞雷神之术被火影村的村民称为金色闪光。

Android+《火影忍者》活动启动模式以及应用场景的那些事_第7张图片

但是这个火影村当时为了自己的孩子甘愿牺牲了自己。
在那个夜晚,他遇到了戴面具的神秘人。
并与之展开了激烈的大战。

波风水门VS宇智波带土

这场战斗充满亮点,让我们来分析一下本场战斗。
1.首先 他本身就是一个活动,这个活动是singleTask启动模式。
2.此时由于带土能够将攻击无效化,所以他准备给以奇袭。
3.掏出自己的手里剑 一个新活动
Android+《火影忍者》活动启动模式以及应用场景的那些事_第8张图片

4.抛出这个手里剑,将手里剑这个活动入栈,此时手里剑处于栈顶位置,优先攻击宇智波带土
Android+《火影忍者》活动启动模式以及应用场景的那些事_第9张图片

5.在手里剑穿过带土触发了带土的攻击实体化后,带土即将碰触到水门的那一刻
Android+《火影忍者》活动启动模式以及应用场景的那些事_第10张图片
6.施展飞雷神之术!一个新的波风水门活动启动,此时由于这个活动是singleTask模式,在这个栈内已经存在,所以再次创建该活动时,在这个活动之上的所有活动统统出栈!Android+《火影忍者》活动启动模式以及应用场景的那些事_第11张图片

7.水门再次处于栈顶!施展螺旋丸!

Android+《火影忍者》活动启动模式以及应用场景的那些事_第12张图片

正经时间:

singleTask模式,每次启动该活动的时候系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。

原理图如下:
Android+《火影忍者》活动启动模式以及应用场景的那些事_第13张图片

简单的代码示例:
由于不是默认模式,所以我们在创建活动的时候,需要到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模式

然后这时候鸣人就可以搓丸子了

Android+《火影忍者》活动启动模式以及应用场景的那些事_第14张图片

在这种状态下,丸子处于栈顶,当我们继续搓来保持这个丸子的时候,就是我们在创建一个同样的活动来让丸子仍然处于栈顶。让我们来写一下代码:

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模式,在启动活动时如果发现返回栈的栈顶已经是该活动,则可以认为直接使用它,不会再创建一个新的活动。但是当这个活动不处于栈顶,那么还需要在重新创建一个新的活动压入栈并置于栈顶位置。

原理图如下:
Android+《火影忍者》活动启动模式以及应用场景的那些事_第15张图片

应用场景:singleTop适合接收通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的,从外界可能多次跳转到一个界面。
摘自 chun_soft

4.尾兽·九尾:singleInstance

鸣人在小时候不知道的是,当初自己的父亲和母亲牺牲自己,将九尾放入他的体内,让他成为了九尾的人柱力。这也就是为什么村民们如此惧怕他。
九尾充满着怨恨,企图控制鸣人。
Android+《火影忍者》活动启动模式以及应用场景的那些事_第16张图片
但是鸣人用自己的执著和乐观感化了九尾,自此之后,鸣人和九尾并肩作战。在后面甚至可以召唤出体外进行作战。
Android+《火影忍者》活动启动模式以及应用场景的那些事_第17张图片
这是为什么呢,其实是因为鸣人懂得了singeleInstance模式。
这种模式的特点是:

该模式的活动会启动一个新的返回栈来管理这个活动(如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。

这种模式下的鸣人到底有啥厉害的呢?请仔细看这个例子。

在没有这种模式下的鸣人,只能依靠螺旋丸等普通的技能,还远远不到开挂的地步。

鸣人这个活动启动螺旋丸或者影分身是这样的 鸣人->螺旋丸 。
但是!

此时此刻,鸣人拥有了九尾。
这种情况下

鸣人召唤了九尾

鸣人->九尾
九尾作为一个独立的个体,拥有强大的战斗力 甚至可以放尾兽玉这个BUG技能!
但是尾兽玉始终是属于九尾的力量。

于是乎 九尾被放在了一个新的栈中 这个栈就叫九尾不能说的秘密

在这个栈中 九尾->尾兽玉

所以当处于singeleInstance模式下的鸣人,是这样放技能的。
鸣人->九尾->尾兽玉->螺旋丸
在这种情况下 鸣人与螺旋丸在一个栈中,由于鸣人召唤了九尾,九尾和尾兽玉则在一个新的栈中。

那么鸣人这时候要如何停止这个模式呢?

首先点一次back,鸣人收回了螺旋丸

由 4->1 因为此时九尾和尾兽玉并不在这个栈中。
然后在点一次back,这时候鸣人在栈顶,就可以准备回收九尾了,于是乎九尾的栈就显示出来了,栈顶还是尾兽玉呢

由1->3(3是2和3这个栈的栈顶)
在点一次back,尾兽回收了尾兽玉 由 3->2
在点一次back,鸣人回收了尾兽,新生成的栈消失了。2->1
再点一次back,鸣人结束了战斗。 np!!!

原理图如下:
Android+《火影忍者》活动启动模式以及应用场景的那些事_第18张图片

应用场景:singleInstance适合需要与程序分离开的页面。例如闹铃提醒,将闹铃提醒与闹铃设置分离。

希望大家可以通过这几个小例子理解安卓活动的启动模式之间的区别,很少写博客,写的不是很好,希望见谅。

最后附上名场面:
Android+《火影忍者》活动启动模式以及应用场景的那些事_第19张图片
一袋米要抗几楼
一袋米要抗二楼
一袋米要我给多嘞
一袋米要有洗尼
口口有泥
谁给你的一袋米楼
辛辣填sei!!!!
Android+《火影忍者》活动启动模式以及应用场景的那些事_第20张图片

你可能感兴趣的:(Android)