Activity启动模式以及在使用时需要注意的地方

时间:2022-04-14 06:52:51
 一 Activity的启动模式 standard,singleTop,singleTask,singleInstance,每种模式的特点
   
(1) standard (默认是标准的)
     a) 每次启动Activity时,都会创建该Activity的新实例

 b) 在任务中使用startActivity方法启动Activity时,  该Activity在当前任务的Activity栈中创建新实例。

         c) 同一个任务中可以包含同一Activity的多个实例

 d) 同一Activity的多个实例可以出现在不同的任务中

   (2) singleTop
a) 当该模式的Activity不位于栈顶时,其表现与标准模式的activity一致。
b) 当该模式的Activity位于栈顶时,  使用startActivity重复启动该Activity并不会创建该Activity的新实例,
     而是调用原栈顶的Activity实例的 onNewIntent方法 将本次启动的intent对象传入到该实例中。

   (3) singleTask
a) 设置为singleTask的Activity是单例的,即在同一时刻Android系统只能存在该Activity的一个实例,
所以当重复启动该Activity时,并不会创建该Activity新实例,而是重新使该Activity的实例
进入可交互状态。
如果该Activity的实例不位于当前任务的栈顶,则将该实例之上的所有Activity释放(销毁),
以使该Activity重新成为栈顶

b)当该模式的Activity在第一次创建时,

           如果所在任务的taskAffnity值与该Activity的taskAffinity值相同,则直接在该任务中创建该Activity的实例,

           如果该任务的taskAffinity与该Activity的taskAffinity值不同,则在新的task中创建该实例。
 
   (4) singleInstance
 a) 该模式的Activity是单例的, 即在同一时刻Android系统中只能存在该Activity的一个实例
  所以当重复启动该Activity时候,并不会创建该Activity的新实例。

         b) 该模式的Activity的实例不会与其他Activity实例同处于一个任务栈中,

    所以当通过该Activity实例去启动其它的Activity时,其它Activity的新实例不会在该任务中直接创建。
           如果其它Activity的新实例的吸附值与现存某任务的吸附值一致,则在与其吸附值一致的任务中创建,
           如果没有与其吸附值相同的现存任务,则在新任务中创建

c) 该模式的Activity实例第一次创建时一定创建在一个新的任务中。


二 Activity startAcivityForResult

(1)  Activity 调用 startAcivityForResult(Intent intent,int requestCode)  
  此方法是启动一个Activity,你启动的Activity退出的时候会回调onActivityResult(int requestCode,int resultCode,Intent data)方法,
 条件是startAcivityForResult(Intent intent,int requestCode)中的requestCode >=0
 如果requestCode为负数, 那么startAcivityForResult会和startActivity一样, 不会回调onActivityResult()方法的

(2)  Activity不同启动模式下startActivityForResult()不同的结果:
      所在的Activity的它的方法onActivityResult(int requestCode,int resultCode,Intent data)的调用时机不同:

  Eg:ActivityA  -> ActivityB 在ActivityA中启动ActivityB

(a) ActivityA启动模式为standard/singleTop,ActivityB的启动模式为standard/singleTop,
      ActivityA的onActivityResult方法会在当前的ActivityB结束掉之后被调用
(b) ActivityA启动模式为singleTask/singleInstance,不管ActivityB启动模式为哪种,
      ActivityA的onActivityResult方法会立即被调用,并马上收到一个取消的结果resultCode=0(RESULT_CANCELED),
      在ActivityB中setResult()不再起作用了
(c) ActivityA启动模式为standard/singleTop,ActivityB的启动模式为singleTask/singleInstance,
     结果同(b): ActivityA的onActivityResult方法会立即被调用,并马上收到一个取消的结果resultCode=0(RESULT_CANCELED),
     在ActivityB中setResult()不再起作用了

四 Activity的属性android:taskAffinity="" 任务吸附值(亲族值)(同族)

  android:taskAffinity
  (1) 吸附,亲族
  (2) 每一个Activity都会有一个taskAffinity值,如果未明确设置,则该Activity的taskAffinity值
       与其所在的application的taskAffinity值一致。
  (3) 每一个application 都有一个taskAffinity值,如果没有设置,则该值等于该应用程序的主包的包名
  (4) 每一个task都有一个taskAffinity值,task的taskAffinity值与其Activity栈中栈底的Activity的
        taskAffinity值一致。


五 Main Activity启动模式不同,点击Home键,然后重新点击应用图标出现的页面也会不同的

eg:

<activity
            android:name=".activity.ActivityA"
            android:screenOrientation="portrait"
            android:launchMode="singleTop"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

  ActivityA(Main Activity) -> ActivityB -> ActivityC
    当前页面停留在ActivityC,此时点击Home键,然后重新点击应用图标出现的页面不同:
(1) ActivityA 启动模式为standard/singleTop 能够回到点击Home之前的页面(ActivityC)
(2) ActivityA 启动模式为singleTask/singleInstance,停留在了ActivityA页面,不能回到点击Home键之前的页面(ActivityC)