ホームページ  >  記事  >  WeChat アプレット  >  アクティビティ起動モードを見てみましょう

アクティビティ起動モードを見てみましょう

coldplay.xixi
coldplay.xixi転載
2020-12-10 17:10:452989ブラウズ

小規模プログラム開発チュートリアルActivity 起動モードに関する関連情報を中心に紹介

アクティビティ起動モードを見てみましょう

推奨 (無料): 小規模プログラム開発チュートリアル

序文

通常、アクティビティを開始するときは、Activity を直接開始します。アクティビティの起動モードデフォルトでは、以下はすべてデフォルトの起動モードで起動されます。しかし、場合によっては起動モードの方が重要です。たとえば、アクティビティを 1 回だけ開始し、複数のインスタンスを持たないようにしたい場合は、アクティビティをシングルタスク モードに設定する必要がある場合があります。したがって、これらの起動モードを理解する必要があります。同時に、スタートアップ モード ≠ スタートアップ モードにも注意してください。スタートアップ モードとは、表示起動と暗黙的起動を指します。混同しないようにしてください。表示起動と暗黙的起動については、後ほど別の記事で説明します。

タスク スタックの概要について

スタートアップ モードを理解するには、まずタスク スタックの概念を理解する必要があります。タスクスタックの実装原理についてはここでは詳しく説明しませんが、ここではタスクスタックとは何かについて簡単に紹介します。開始したアクティビティ インスタンスは、タスク スタックと呼ばれるものに配置されます。スタックには「後入れ先出し」の特性があることは誰もが知っています。たとえば、タスク スタックはバドミントンのチューブ、アクティビティ インスタンスは 1 つずつバドミントンで、最後に入れられたものは最初にのみ取り出すことができます。したがって、アプリを起動すると、タスク スタックが自動的に作成され、そこにアクティビティ インスタンスをスローします。 Return キーを押してアクティビティを破棄すると、これらのアクティビティがタスク スタックから順番に取り出されます。もちろん、アプリには複数のタスク スタックを含めることができます。たとえば、singleInstence を使用して開始されたアクティビティは、独立したタスク スタックにあります。タスク スタックの概念を理解した後、アクティビティの 4 つの起動モードを見てみましょう。

Activity の 4 つの起動モードの分析

standard

これは標準の起動モードであり、デフォルトはこの起動モードです。この起動モードのアクティビティが開始されるたびに、同じインスタンスがスタックにすでに存在するかどうかに関係なく、新しいインスタンスが作成されてスタックに配置されます。これも一番分かりやすいですね。

singleTop

名前が示すように、スタックの最上位は単一のインスタンスです。それはどういう意味ですか。ここで ActivityA を開始するとします。ただし、この時点ではすでに ActivityA インスタンスがスタックの最上位にあるため、この時点では新しいインスタンスは作成されません。ただし、同じインスタンスがスタックの最上位に存在する場合でも、新しいインスタンスが作成されます。たとえば、スタック内の現在のアクティビティは ABC で、A がスタックの最上位にあります。この時点で A が開始されると、別の A アクティビティは作成されませんが、A の onNewIntent メソッドが実行されますが、この時点で C アクティビティが開始されると、A はスタックの最上位にある C ではないため、新しい Cインスタンスはまだ作成されますが、この時点のスタック状況は CABC です。

singleTask

シングルタスク モード。このモードは、スタックの最上位にあるかどうかに関係なく、アクティビティの起動スタックには 1 つのインスタンスのみが存在できることを意味します。他の起動モードとは異なり、この起動モードでは起動するスタックを指定できます。たとえば、スタック Main がありますが、アクティビティ A にスタック名 dev を指定できます。その後、A が開始されると、dev というスタックが作成されます。つまり、singleTask が意味するのは、singleTask のスタートアップ モードでアクティビティを開始すると、スタック内に同一のインスタンスが存在しない場合は、新しいインスタンスが作成されてスタックに配置され、指定されたスタックに同じインスタンスが存在する場合は、たとえば、スタックに ABC があり、次に B を開始すると、この時点では新しい B インスタンスは作成されませんが、B をスタックの先頭に置き、A をプッシュしてから、B の onNewIntent メソッドを実行します。今回のスタック状況はBCです。
注意深い読者は「トップアウト」に気づくでしょう。はい、スタックは後入れ先出しであることは誰もが知っています。たとえば、チューブに 3 つのバドミントンを入れた場合、真ん中のバドミントンを取りたい場合は、最初に一番上のバドミントンを取り出すことしかできません。理由は、B をスタックの一番上に持ち上げたい場合は、A を押し出す必要があるからです。多くの読者は起動後は BAC であると誤って考えるかもしれませんが、B が出てくる前に A がスタックから飛び出す必要があるため、実際には BC です。同様に、スタックに ADFBC がある場合、このスタートアップ B も BC となり、上記のものはすべてスタックからポップされます。

singleInstance

シングル インスタンス モード。これは、singleTask の拡張バージョンです。彼は自分で新しいスタックを作成し、この新しいインスタンスをその中に置きます。このスタックはこのアクティブなインスタンスのみを保持できます。したがって、このアクティビティが繰り返し開始されると、このアクティビティが存在する限り、このアクティビティの onNewIntent メソッドが呼び出されてこのスタックに切り替えられ、新しいインスタンスは作成されません。

起動モードを設定する 2 つの方法

アクティビティの 4 つの起動モードを理解した後、起動モードを指定する方法を見てみましょう。

静的設定

静的設定とは、AndroidManifest の特定のアクティビティの起動モードを設定することです。アクティビティの launchMode パラメーターを指定して、起動モードを設定します。例:

 <activity android:name=".MainActivity"
      android:launchMode="singleInstance"/>

動的設定

動的設定では、アクティビティを開始するときの起動モードを指定します。例:

Intent intent = new Intent();
intent.setClass(this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

可以看到我们通过intent.addFlags这个方法来指定启动模式,这个方法传入一个参数来指定启动模式,其他的参数有:

  • FLAG_ACTIVITY_NEW_TASK:singleTask模式
  • FLAG_ACTIVITY_SINGLE_TOP:singleTop模式
  • FLAG_ACTIVITY_CLEAR_TOP:清除该活动上方的所有活动。一般和singleTask一起使用。但是如果你的启动模式是standard,那么这个活动连他之上的所有活动都会被出栈再创建一个新的实例放进去。例如现在栈中是ABCD,以FLAG_ACTIVITY_CLEAR_TOP+standard模式启动C的时候,首先清理掉ABC,是的,C也会被清理,然后再创建一个新的C放进去,执行之后就是CD。

特别注意的坑

singleInstance返回任务栈

现在模拟一个场景:现在有三个活动 A,B,C。A和C的启动模式都是standard,B的启动模式是singleInstance。先启动A,再启动B,然后再启动C。这个时候问题来了,如果我这个时候按下返回键,是回到B吗?答案是回到A。再按一下呢,返回桌面吗?答案是回到B,再按一下再回到桌面。其实不难理解。我们都知道singleInstance会创建一个独立的栈,当我们启动A的时候,A位于栈First中,启动B的时候,就会创建一个栈Second并把B实例放进去。这个时候再启动C,就会切换到栈FIrst,因为singleInstance创建的栈只能放一个,所以C会放到栈First中,当按下返回的时候,栈First中的活动就会依次出栈,直到全部出完,才会切换到栈Second中。所以要注意这个点。

singleTask多任务栈启动问题

这个问题和上面singleTop的本质是一样的。模拟一个场景:现在有两个栈:First:ABC;Second:QWE。栈First位于前台,栈Second位于后台。A位于栈顶。这个时候以singleTask的模式启动W,会发生什么样的情况呢?首先会切换到栈Second,再把Q出栈,W提到栈顶,并执行W的onNewIntent方法。这个时候按返回键就会把Second栈中的活动依次出栈,全部出完后才会切换到栈First。

singleTask的TaskAffinity与allowTaskReparenting参数

前面我们讲到给singleTask模式指定要启动的任务栈的名字,怎么指定呢?可以在AndroidManifest中指定相关的属性,如下:

<activity android:name=".Main2Activity"
     android:launchMode="singleTask"
     android:taskAffinity="com.huan"
     android:allowTaskReparenting="true"/>

这里解释一下这两个参数

  • taskAffinity:指定任务栈的名字。默认的任务栈是包名,所以不能以包名来命名。
  • allowTaskReparenting:这个参数表示可不可以切换到新的任务栈,通常设置为true并和上面的参数一起使用。

我前面讲到可以给singleTask的活动指定一个栈名,然后启动的时候,就会切换到那个栈,并把新的活动放进去。但是如果设置allowTaskReparenting参数为false的话是不会切换到新的栈的。这个参数的意思是可不可以把新的活动转移到新的任务栈。简单点来说:当我们启动一个singleTask活动的时候,这个活动还是留在启动他的活动的栈中的。但是我们指定了taskAffinity这个参数,或者启动的活动是别的应用中的活动,那么就会创建一个新的任务栈。如果allowTaskReparenting这个参数是true的话,那么这个活动就会放到那个新的任务栈中。这样应该就可以明白了。所以这两个经常是配套一起使用的。

总结

活动的启动模式有四种,每种的功能都不一样,可以结合具体需要去使用,但是最重点还是要了解他的实现原理,栈中是怎么变化的,这个是比较重要的。了解这个之后那些特殊情况也就很容易理解了。
上面我讲的只是简单的使用,关于活动启动模式还有很多要了解。后续可能会解析一下,读者也可以自行去深度了解。

相关免费推荐:编程视频课程

以上がアクティビティ起動モードを見てみましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjb51.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。