Activity起動モード(二)Activityの4種類の起動モード――LaunchMode
10261 ワード
4種類の起動モード
Standard
標準モードでは、Intentリクエストがあるたびに新しいActivityインスタンスが作成されます.
```
TaskRecord{537925a8 #42 A com.zlq.lmt U 0} Run #3: ActivityRecord{538314d0 com.zlq.lmt/.StandardActivity} Run #2: ActivityRecord{5385a7c4 com.zlq.lmt/.StandardActivity} Run #1: ActivityRecord{53760908 com.zlq.lmt/.MainActivity}
2.
Activity, Intent Task ( , )。
```
TaskRecord{537df318 #52 A com.zlq.bbb U 0}
Run #2: ActivityRecord{537a889c com.zlq.lmt/.StandardActivity}
Run #1: ActivityRecord{537a4a5c com.zlq.bbb/.MainActivityB}
このとき、タスクマネージャ(最近のタスクボタン)を開きます.最近のタスクの現実的なアプリケーション名はBアプリケーションであり、表示されるインタフェースはTaskスタックの上部にあるため、AアプリケーションのStandardActivityであることがわかります.
アプリケーション間Standard Activityの起動
Android Activity launchMode
の内容は間違っているかもしれません.SingleTop
スタックトップ多重モードSingleTopはStandardとほぼ同じであり、SingleTopのActivityを使用して多くのインスタンスを作成することもできます.唯一の違いは、呼び出されたターゲットActivityがすでに呼び出し元のTaskのスタックの上部にある場合、新しいインスタンスは作成されず、現在のこのActivityインスタンスを使用して、このインスタンスのonNewIntentメソッドを呼び出すことです.
singleTopというモードでは,このモードを適用したActivityのonCreateとonNewIntentの2つの方法を処理し,論理が正常であることを確保する必要がある.
TaskRecord{537925a8 #42 A com.zlq.lmt U 0}
Run #4: ActivityRecord{537e3114 com.zlq.lmt/.SingleTopActivity}
Run #3: ActivityRecord{537dfe7c com.zlq.lmt/.StandardActivity}
Run #2: ActivityRecord{53770808 com.zlq.lmt/.SingleTopActivity}
Run #1: ActivityRecord{53760908 com.zlq.lmt/.MainActivity}
スタックトップはStandardモードのように同僚が2つ存在することはできませんが、Taskリスト全体に複数の間隔が存在することは可能です.
SingleTask
スタック内多重モードsingleTask起動モードを使用するActivityは、1つのアプリケーションTaskに1つのインスタンスしか存在しません.このインスタンスがすでに存在する場合、intentはonNewIntentを介してこのActivityに渡されます.つまり、複数回の呼び出しで新しいインスタンスは作成されません.それ以外の場合、新しいActivityインスタンスが作成されます.状況は以下のとおりです.
The system creates a new task and instantiates the activity at the root of the new task.
Task, Activity Task 。 , ,singleTask Activity Task, Task:
TaskRecord{5378ff88 #44 A com.zlq.lmt U 0}
Run #3: ActivityRecord{537e2ff0 com.zlq.lmt/.SingleTaskActivity}
Run #2: ActivityRecord{537de2ec com.zlq.lmt/.StandardActivity}
Run #1: ActivityRecord{53788be0 com.zlq.lmt/.MainActivity}
? `taskAffinity` singleTask .
```xml
```
このとき、同じ操作を実行し、スタック内の場合:
TaskRecord{53778428 #45 A com.zlq.new U 0}
Run #3: ActivityRecord{537db410 com.zlq.lmt/.SingleTaskWithTaskAffinityActivity}
TaskRecord{5378ff88 #44 A com.zlq.lmt U 0}
Run #2: ActivityRecord{53760908 com.zlq.lmt/.StandardActivity}
Run #1: ActivityRecord{53788be0 com.zlq.lmt/.MainActivity}
,** singleTask,framework activity , , 。** `taskAffinity` Activity , SingleTask , Standard . com.zlq.new.
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #0: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
次のようになります.
TaskRecord{5c70a93 #17 A=com.zlq.lmt U=0 sz=1}
Run #1: ActivityRecord{4cd8b0f u0 com.zlq.lmt/.SingleTaskActivity t17}
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #0: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
最近のタスクの変更:
ここに画像の説明を入力します
次のようになります.
ここに画像の説明を入力します
Running activities (most recent first):
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #1: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=1}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
↓は↓になります.
Running activities (most recent first):
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #2: ActivityRecord{73d091c u0 com.zlq.lmt/.SingleTaskActivity t18}
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #1: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
Running activities (most recent first):
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #4: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=4}
Run #3: ActivityRecord{fa7aae9 u0 com.zlq.lmt/.StandardActivity t18}
Run #2: ActivityRecord{dfd9a3b u0 com.zlq.lmt/.StandardActivity t18}
Run #1: ActivityRecord{660ce3c u0 com.zlq.lmt/.SingleTaskActivity t18}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
↓は↓になります.
Running activities (most recent first):
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #2: ActivityRecord{660ce3c u0 com.zlq.lmt/.SingleTaskActivity t18}
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #1: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
TASK IDが
#18
のタスクスタックは、従来の4
個から最終的な1+1
個に変わったことがわかる.SingleInstance
単一インスタンスモードが起動すると、システムは単独のタスクスタックを作成し、その後使用するたびに、この単一インスタンスを破棄するまで使用し、真の単一インスタンスモードに属する.singleTaskの差は多くありませんが、singleInstance Activityインスタンスを格納するTaskは、このモードのActivityインスタンスを1つしか格納できず、他のActivityインスタンスは存在しません.2つのtaskですが、システムのタスクマネージャには常に1つ、すなわち上部にあるTaskが表示されます.
関連知識点
現在のタスクスタックを表示するには、次の手順に従います。
adb shell dumpsys activity | sed -n -e '/Stack #/p' -e '/Running activities/,/Run #0/p'
出力の結果は次のとおりです.Running activities (most recent first):
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #2: ActivityRecord{660ce3c u0 com.zlq.lmt/.SingleTaskActivity t18}
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #1: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
を例にとると、TaskRecordの先頭の(例えば)はTaskRecordレコードのセットであり、18はTaskのIDであり、A=パケット名であり、szはこのTaskのActivity数である.Run#で始まるActivityレコード.パッケージ名、クラス名、TASK IDなどの情報も含まれている.
ここで、Task IDを1つのタスクスタックの一意の識別とし、IDが同じTaskRecordは同じタスクスタックに属する(同一のアプリケーションとして理解できる).
startActivity ForResultへの影響:
startActivity ForResultはstartActivityとは異なり、startActivity ForResultを使用する場合、LaunchModeがどのモードに設定されているかにかかわらず、呼び出し元Taskスタックにインスタンスが新規作成され、データが正しく返されます.スタック内の表示形式はStandardと同じです(連続したインスタンスを複数生成できます).
adb shell dumpsys activity | sed -n -e '/Stack #/p' -e '/Running activities/,/Run #0/p'
Running activities (most recent first):
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #2: ActivityRecord{660ce3c u0 com.zlq.lmt/.SingleTaskActivity t18}
TaskRecord{5bf28 #16 A=com.zlq.bbb U=0 sz=1}
Run #1: ActivityRecord{f4a1b15 u0 com.zlq.bbb/.MainActivityB t16}
TaskRecord{65dfdf0 #18 A=com.zlq.lmt U=0 sz=2}
Run #0: ActivityRecord{f0eba63 u0 com.zlq.lmt/.MainActivity t18}
Running activities (most recent first):
TaskRecord{ef9f20b #33 A=com.zlq.lmt U=0 sz=4}
Run #3: ActivityRecord{34f60b1 u0 com.zlq.lmt/.SingleTaskActivity t33} *
Run #2: ActivityRecord{914547d u0 com.zlq.lmt/.SingleTaskActivity t33} *
Run #1: ActivityRecord{a1f3e09 u0 com.zlq.lmt/.SingleTaskActivity t33}
Run #0: ActivityRecord{f7db1c u0 com.zlq.lmt/.MainActivity t33}
上のコードセグメントには、startActivityを使用して確立できないことを示す
*
が付いており、startActivityForResult
を使用して確立されたActivityである.このことから、startActivity ForResultは戻り値を必要とするため、インスタンスが保持する、単例の効果が部分的に上書きされることが分かる.注意:4.xバージョンはstartActivity ForResultでsingleTaskを起動し、正常に戻り値を取得できません.参考.5.x以上のバージョンでこの問題を修正し、互換性を考慮してstartActivity ForResultとsingleTaskを推奨しない.
Demoソース
以上はいずれも参考資料と自己実践検証の結果である.説明がはっきりしないところがあって、みんなは私のコードをダウンロードして自分で各種の情況を検証することができます:GitHub
リファレンスリンク
AndroidのActivity launchMode分析Activityの起動モードAndroidのActivityの4種類の起動モードとtaskAffinityの属性の詳細を詳しく説明します
AndroidのActivity launchMode分析Activityの起動モードAndroidのActivityの4種類の起動モードとtaskAffinityの属性の詳細を詳しく説明します