3.Activityの起動モードとタスクスタック学習ノート


Activityの起動モードに詳しいと思っていたのですが、少し忘れてしまったので、ここでもう一度勉強します.
まず、Activityの起動モードは4つに分けられ、様々なプロジェクトのニーズを満たすために、Activityの起動モードとフラグビットを理解する必要があります.
3.1 ActivityのLaunchMode
    
   
3.1.1 standard:標準モード、つまりシステムのデフォルトモード.
    
Activityを起動するたびに新しいインスタンスが作成されます.このActivityに実力があるかどうかにかかわらず、複数回起動するActivity宣言サイクルも通常のライフサイクルに合致します.これは典型的なマルチインスタンス実装であり、1つのタスクスタックに複数のインスタンスがあり、各インスタンスが異なるタスクスタックに属してもよい.この場合、誰がこのActivityを起動すると、このActivityはそのActivityが起動したスタックの中で実行されます.
ここで、ApplicationContextを使用してStandardモードのActivityを起動すると、次のようにエラーが表示されます.
    android.util.AndroidRuntimeException:   Calling startActivity from outside of an Activity requires the FLAG_ACTIVITY_NEW_TASK flag.Is this really what you want ?
このエラーは、ある放送でContextで新しい標準のActivityを直接起動するなど、よく発生します.これは、standardモードのActivityは、ActivityタイプのContext(ApplcationContextなど)ではなく、Activityを起動するタスクスタックにデフォルトで入るため、問題が発生します.これを解決するのが起動時にフラグを設定することです:FLAG_ACTIVITY_NEW_TASK.これにより、このActivityに個別のタスクスタックが作成され、このとき起動するActivityは実際にsingleTaskで起動されます(存在しない方法で起動されます).
  
3.1.2 singleTop:スタックトップ多重モード.
この場合、作成するActivityのインスタンスがすでにタスクスタックのスタックトップにある場合は再作成されませんが、このActivityを呼び出すonNewIntentメソッド(onCreate、onResumeメソッドは呼び出されません)、onNewIntentメソッドにより、リクエストの情報をIntentから取り出すことができます.
    
3.1.3 singleTask:スタック内多重モード.
これは、ActivityスタックにActivityのインスタンスが存在する限り、複数回の呼び出しで新しいインスタンスは作成されませんが、onNewIntentが呼び出されます.
具体的には、singleTaskモードを持つActivityリクエストが起動すると、Activity Aのように、まずAが望むタスクスタックが存在するかどうかを探します.存在しない場合は、タスクスタックを再作成し、存在しない場合は新しいタスクスタックを作成し、Aを作成したインスタンスをスタックに配置します.存在する場合は、このタスクスタックにAのインスタンスが存在するかどうかを見て、インスタンスが存在する場合は、Aをスタックの上部に調整してから、インスタンスの上のActivityを削除し、onNewIntentメソッドを呼び出します.Aがこの所望のタスクスタックに存在しない場合、Aの実力が作成され、Aがスタックに押し込まれる.
例えば、タスクスタックS 1にABCがあり、singleTaskはActivity Dを起動し、DはS 2に入りたい.S 2もDもないなら、S 2を作成し、DをS 2に入れる.
Dに必要なS 1,S 1が存在し,Dが存在しない場合は,Dを作成してS 1に入れる.最後のS 1はABCD もう1つの場合、S 1は存在し、Dも存在し、DはS 1に入りたいと思って、順番はADBCで、Dはスタックの上に置かれ、Dの前のものはclearに落とされます.
   
   
3.1.4 singInstance:シングルインスタンスモード.
このモードは強化バージョンのsingleTaskモードであり,このモードのActivityは1つのスタックに単独でしか存在しない.
   
    
3.1.5起動モードの指定
起動モードを指定するには2つあります.1つはAndroidManifestです.xmlでは、Activity宣言で起動モードを指定します.たとえば、次のようにします.
<activity android:name=".Main2Activity"
android:allowTaskReparenting="true"
android:launchMode="singleTask"
></activity>

また、Activityの起動モードは、Intentにフラグビットを設定することで指定することもできます.
    Intent intent = new Intent();
    intent.setClass( MainActivity.Class,SecondActivity.class);
    startActivity( intent );
    
どちらもActivityの起動モードを指定できますが、違いがあります.
優先順位:2番目が1番目より高い.
制限範囲が異なり、1つ目はActivityフラグに直接指定できません:FLAG_ACTIVITY_CLEAR_TOP(ただしsingleTaskはデフォルトでこの機能を持っている)では、2つ目はActivityにsingleInstance を指定できません.
    
3.2タスクスタック
タスクスタックとは何ですか?Taskスタックを理解するには、次の手順に従います.
Activityのaffinity IntentのFlag Activity Taskのプロパティについて
ここでは,まずパラメータTaskAffinityから述べる.
    3.2.1 TaskAffinity
TaskAffinityは、タスク依存性と訳すことができます.Activityに必要なタスクスタックの名前を識別するパラメータです.つまり、SingleTaskが言う必要なタスクスタックについて説明します.デフォルトでは、このすべてのActivityに必要なスタック名がパッケージ名です(パッケージ名は一意です).もちろん、ActivityごとにTaskAffinityプロパティを個別に作成できます.このプロパティ値はパッケージ名と同じでなければなりません(自分のパッケージ名だけでなく、他のアプリケーションパッケージ名も重複できません).そうしないと、指定されていないことになります.TaskAffinityプロパティは、主にsingleTask起動モードまたはallowTaskReparentingプロパティとペアで使用されますが、他の場合は意味がありません.また、タスクスタックには、フロントタスクスタックとバックグラウンドタスクスタックがあります.バックグラウンドタスクスタックのActivityは一時停止状態にあり、ユーザーは切り替えてバックグラウンドタスクスタックを再びフロントに移動することができる.(どのように呼び出しますか?参考:http://blog.csdn.net/chaoyue0071/article/details/43791909後で説明します)
    
TaskAffinityとsingleTask起動モードがペアで使用される場合、このモードのActivityを持つ現在のスタックの名前であり、起動するActivityはTaskAffinityと同じ名前のタスクスタックで実行されます.
TaskAffinityとallTaskReparentingが結合すると、いくつかの特殊な効果が発生します.例えば、アプリケーションAがアプリケーションBのいずれかのActivityを起動すると、このActivityのallTaskReparenting属性がTrueであれば、アプリケーションBが起動すると、そのActivityはアプリケーションAのタスクスタックからアプリケーションBのタスクスタックに直接移行する.例えば、AアプリケーションとBアプリケーションでは、AアプリケーションがBのいずれかのActivity Cを起動し、ホームを押してデスクトップに戻り、最後にBアプリケーションをクリックして飛び出したのは、MainActivityではなくBアプリケーションのActivity Cです. 
質問:TaskAffinityとsingleTaskを組み合わせるとき、TaskAffinity+allTaskReparentingとはどんな違いがありますか?    
違いは、前者がActivity Cを作成するとBのタスクスタックが作成され、後者は現在Aのタスクスタックが実行され、Bが起動してタスクスタックBが作成されると、CがタスクスタックAからタスクスタックBに移行することである.  
3.2.2 Activityの一般的なFlags
FLAG_ACTIVITY_NEW_TASK
Activity起動モードを「singleTask」モード、効果、AndroidManifestに指定します.xmlでは、起動モードと同じように指定します.
FLAG_ACTIVITY_SINGLE_TOP
Activity起動モードが「singleTop」モードであることを指定します.
FLAG_ACTIVITY_CLEAR_TOP 
このタグビットを使用してActivityを起動すると、タスクスタックの上にあるすべてのActivityがポップアップされます.singleTaskモードではデフォルトでこの効果があります.
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
このActivityは履歴Activityのリストには表示されません.場合によっては、ユーザーが履歴リストからこのActivityを取り戻すことを望んでいない場合があります.このタグビットを使用することができます.AndroidManifestでxmlではandroid:excludeFromReents="true"を使用します.BはA->B->Cのようにマークされており、Cは戻りキーを押すとAに戻ります.
3.3フロントタスクスタックとバックグラウンドタスクスタック
個人的には、フロントタスクスタックは現在フロントで実行されているActivityのセットであり、Activityのセットであってもよい.例えば、スタックAがフロントで実行され、スタックBがバックグラウンドで実行され、スタックAがスタックBのActivityを呼び出すと、スタックBはフロントで実行され、スタックB全体のActivityリストがスタックAのActivityリストに重ねられ、Backを押し続けるとスタックBが空になってからスタックAに入る.このときスタックA、スタックBはフロントで動作する.ホームキーなどを押すと、スタックAとスタックBの両方がバックグラウンドに入って運転を一時停止します.