Activity起動モードおよびタグビット

12930 ワード

Activity起動モード


activity起動モードについて話す前に、activityスタックの概念を理解します.Activityタスクスタックは、「後進先出」のスタック構造です.すなわち、新しいactivityインスタンスを起動するとスタックの上部に押し込まれ、activityが戻りキーを押して終了すると、インスタンスはタスクスタックからスタックを出ます.タスクスタックはフロントタスクスタックとバックグラウンドタスクスタックに分けられ、バックグラウンドタスクスタックのactivityは一時停止状態にあり、ユーザーは切り替えてバックグラウンドタスクスタックを再びフロントに呼び出すことができる.
Activityの起動モードはスタックの動作原理に合わせて、日常の業務ニーズを満たすことです.Activityが起動するモードは、standard、singleTop、singleTask、singleInstanceの4つです.standardはactivityのデフォルトの起動モードです.

Standard:標準モード(デフォルトモード)


このモードのactivityでは、起動するたびに新しいインスタンスが作成され、そのインスタンスがタスクスタック内に存在するかどうかにかかわらずスタックが圧縮されます.activityAとactivityBが標準モードの場合、activityAはactivityBを起動し、スタックトップはactivityB、次はactivityAです.
標準モードのactivityはデフォルトで起動するactivityが属するタスクスタックに入ります.activityタイプ以外のContextが起動するには、タグビットFLAG_を追加する必要があります.ACTIVITY_NEW_TASKは、新しいタスクスタックを再作成します.このフラグビットの起動モードは、実際にはsingleTaskモードで起動されます.(後で説明しますが、ここではタグビットの知識点をスキップします)

コマンドラインスタック内activityリスト情報の表示


例:同じAPP内でタグビットがない場合、activityA-activityB-activityC-activityAのジャンプを実行します.これらはすべて標準モードです.理論上スタック内はABCAであるべきである.
コマンドラインの実行:
 adb shell dumpsys activity

コマンドラインがスタック情報を照会する際の情報は非常に多く雑多であるが、ここでは主にACTIVITIES(dumpsys activity activities)Display#0(activities from top to bottom):その行の下の情報、すなわちHist#3:——Hist#2:——Hist#1:——Hist#0:スタック内の上から下への表示順、Hist#3はスタックの上に位置する.
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #1:
    Task id #319
      TaskRecord{22fe5578 #319 A=com.jzf.myactivity U=0 sz=4}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA }
        Hist #3: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319}
          Intent { cmp=com.jzf.myactivity/.ActivityA }
          ProcessRecord{37252451 3045:com.jzf.myactivity/u0a58}
        Hist #2: ActivityRecord{29295492 u0 com.jzf.myactivity/.ActivityC t319}
          Intent { cmp=com.jzf.myactivity/.ActivityC }
        Hist #1: ActivityRecord{4dcc45c u0 com.jzf.myactivity/.ActivityB t319}
          Intent { cmp=com.jzf.myactivity/.ActivityB }
        Hist #0: ActivityRecord{2bc3c1f6 u0 com.jzf.myactivity/.ActivityA t319}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA }

    Running activities (most recent first):
      TaskRecord{22fe5578 #319 A=com.jzf.myactivity U=0 sz=4}
        Run #0: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319}

    mResumedActivity: ActivityRecord{38af6616 u0 com.jzf.myactivity/.ActivityA t319}

Running activities(most recent first):スタック内のactivity数sz=4と、スタックの上部にあるactivityAも行の下に表示されます.

singleTask:スタック内多重モード


これは、スキーマのactivityがスタックに存在する限り、このactivityを複数回起動してもインスタンスは作成されません.singleTaskモードのデフォルトではclearTop効果があり、スタック内のこのactivity上のすべてのactivityがスタックからすべてアウトになります.このモードでは、activityのonNewIntentメソッドがコールバックされ、activityのonCreateメソッドとonStartメソッドは再実行されません.
例:同じAPP内でタグビットがない場合、実行ジャンプactivityA-activityB-activityC-activityB、activityAとactivityCは標準モード、activityBはsingleTaskモードである.理論的には結果はABであるべきであり,Bはスタックの頂上に位置する.
activityCがactivityBにジャンプしたログは以下の通りです.
D/ActivityC: onPause
D/ActivityB: onNewIntent
D/ActivityB: onRestart
D/ActivityB: onStart
D/ActivityB: onResume
D/ActivityC: onStop
D/ActivityC: onDestroy
D/ActivityC: ————————————————

コマンド・ライン・クエリー・スタックの情報は次のとおりです.
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #1:
    Task id #321
      TaskRecord{280e2df3 #321 A=com.jzf.myactivity U=0 sz=2}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA }
        Hist #1: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321}
          Intent { flg=0x10000000 cmp=com.jzf.myactivity/.ActivityB }
          ProcessRecord{1cfbcab0 3775:com.jzf.myactivity/u0a58}
        Hist #0: ActivityRecord{1b45261d u0 com.jzf.myactivity/.ActivityA t321}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.jzf.myactivity/.ActivityA }

    Running activities (most recent first):
      TaskRecord{280e2df3 #321 A=com.jzf.myactivity U=0 sz=2}
        Run #0: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321}

    mResumedActivity: ActivityRecord{2beb98ab u0 com.jzf.myactivity/.ActivityB t321}

前述したように、Hist#1:はActivity B、Hist#0:はActivity Aであり、タスクスタック全体に2つのactivityがあり、Activity Bはスタックトップに位置する.これはactivityA-activityB-activityC-activityBを説明し、activityC-activityBの場合、スタック内の既存のactivityBインスタンスを多重化し、上に位置していたactivityCを空にします.

singleTop:スタックトップ多重モード


このモードのactivityがタスクスタックのスタックトップにある場合(多重化の前提はこの条件を満たす必要がありますよ~)、このactivityは再作成されず、onNewIntentメソッドがコールバックされます.このactivityのonCreateでは、onStartは変更されていないため、システムによって呼び出されません.

singleInstance:シングルインスタンスモード


簡単に理解すると、これは強化型のsingleTaskモードであり、singleTaskのすべての特性を備えているほか、このモードを備えたactivityは1つのタスクスタックに単独でしか存在しない点がある.singleTaskのスタック内多重化特性を備えているため、このタスクスタックが破棄されない限り、その後の起動によってactivityは新しいactivityを作成しません.

共通タグビット


Activityの起動は、通常Android Menifest.xmlファイルでは起動モードを設定しますが、タグビットも使用される場合があります.ここではよく使われるタグビットとその使い方を簡単に挙げますが、残りの皆さんはソースコードで完全に理解できます~
注意:タグ付きビットの起動モードの優先度はAndroid Menifestである.xmlファイルで指定した起動モード.

FLAG_ACTIVITY_NEW_TASK


このタグビットの意味は、Activityコンテキスト以外でActivityを起動するには、IntentにFLAG_を設定する必要があるということです.ACTIVITY_NEW_TASKフラグは、このActivityにタスクスタックを指定または割り当てます.このモードはactivityが指定する「singleTask」起動モードであり、その効果はAndroid Menifestである.xmlファイルでは、起動モードが同じであることを指定します.この状態を設定すると、まず起動したActivityと同じ親和性を持つタスクスタックが存在するかどうかを検索します(つまりTaskAffinity、同じアプリケーションのactivityの親和性に注意してください).もしあるならば、直接このスタック全体をフロントに移動して、スタックの中の状態を維持して、つまりスタックの中のactivityの順序は変わらない;ない場合は、起動されたactivityを格納するスタックを新規に作成します.

FLAG_ACTIVITY_CLEAR_TOP


このActivityを含むTaskのActivityインスタンスの上にある他のActivityインスタンスをクリアします.
ケース:activityA-activityB-activityC-activityB、activityB起動時に単独で加算
 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

activityCでactivityBを起動すると、ログの一部が次のように印刷されます.
D/ActivityC: onPause
D/ActivityB: onDestroy
D/ActivityB: ————————————————
D/ActivityB: onCreate
D/ActivityB: onStart
D/ActivityB: onResume
D/ActivityC: onStop
D/ActivityC: onDestroy
D/ActivityC: ————————————————

FLAG_ACTIVITY_SINGLE_TOP


launchMode="singleTop"と同じ効果です.
FLAG_ACTIVITY_CLEAR_TOP配合FLAG_ACTIVITY_SINGLE_TOPが使用すると、Bは破棄されず、B以上のインスタンスのみが破棄され、BはonNewIntent->onStartを実行します.
ケース:activityA-activityB-activityC-activityB、activityBを起動する時に2つのタグビットを加えて、activityCがactivityBを起動する時に一部のlogログを印刷するのは以下の通りです:
D/ActivityC: onPause
D/ActivityB: onNewIntent
D/ActivityB: onRestart
D/ActivityB: onStart
D/ActivityB: onResume
D/ActivityC: onStop
D/ActivityC: onDestroy
D/ActivityC: ————————————————