1、onWindowFocusChanged微信
有时咱们须要测量一个Activity多长时间才能显示出来,那么在代码中打点计时的时机选在哪儿呢?在onCreate和onResume执行完成后,Activity的界面仍不可见,在onResume以后,framework还会回调一个叫onWindowFocusChanged的函数,它表示用户是否已经能够与Activity的界面进行交互了。onWindowFocusChanged为true意味着Activity的界面已经可以被用户看到了(天然也能和用户交互了)。实际上activity变为visible的时间点出如今onWindowFocusChanged以前,可是这个状态只能在ActivityManagerService中获取,在客户端仍是只能经过onWindowFocusChanged做为界面可见或不可见的标志。app
在界面变为不可见时,先调用onPause,而后再是onWindowFocusChanged为false。这也容易理解,onPause原本就是Activity被部分遮住时调用的,调用完onPause后才会让界面不能与用户继续交互。函数
若是想加快Activity的启动时间,把在onCreate里一些耗时操做挪到onResume里,有时会发现并无什么变化,因此若是要想先让Activity的界面尽快展示给用户仍是得把这些逻辑放在onWindowFocusChanged变为true以后执行。布局
2、onUserLeaveHint动画
这个回调函数主要用来监听按Home键退出到桌面的动做,发生在onPause以前。在启动一个新的Activity时,ActivityStackSupervisor里会调用startActivityUncheckedLocked,在它里面会给mUserLeaving赋值。mUserLeaving用于指示当前activity退到后台时函数onUserLeaving是否被调用。.net
可见,只有当设置了FLAG_ACTIVITY_NO_USER_ACTION标志时mUserLeaving才会为false,其余状况下mUserLeaving均为true,也就是onUserLeaveHint会被调用,注释里也说了onUserLeaveHint会在onPause以前被调用。xml
3、taskAffinity字符串
task是一组用来处理某一任务的Activity的集合,位于一个回退栈内,当新启动一个应用时framework就会建立一个新的task来承载相应的Activity。taskAffinity用来描述Activity的亲和性,即Activity属于哪一个task。若是在AndroidManifest.xml的application中没显式定义taskAffinity,那么缺省的affinity名字就是包名。同一affinity的Activity会被放在同一task里,task的affinity名字由根Activity的taskAffinity决定,若是根Activity没设taskAffinity属性,则affinity就由application的affinity决定。get
若是taskAffinity设为空字符串,那说明该Activity和其余的task都不存在亲和性。不一样应用的Activity也能够设置相同的affinity,这样当启动后它们就会位于同一task中。 回调函数
4、launchMode
1. standard
默认的launchMode,能够实例化屡次。
2.singleTop
使用这种launchMode的状况是,若是要启动的Activity已经在栈的最顶端,那么startActivity时再也不会从新调用它的onCreate,而是调用它的onNewIntent。但若是要启动的Activity不在栈顶,好比A –> B à C,这时C再启动B,就会再实例化一个新的B,栈里面变成A à Bà C à B。
若是A中点击一个button来启动B,但系统反应慢,用户在极短的时间内点了两次,若是是B是standard,则会有两个B,若是是singleTop则只会有一个。更典型的场景是用户使用外卖App支付了一笔订单后,从支付页面返回到订单详情页面,若是订单的状态有发生变化,好比商家接单了,这时通知栏会有通知,点击通知会跳入订单详情页面。若是此时订单详情页面是standard的话,那么用户按back键后发现仍是在订单详情页面,体验就不好了。若是是singleTop,只需在onNewIntent里更新状态信息,就能够显示出最新的信息,而没必要再新建立一个相同的Activity了。
3.singleTask
以这种模式启动的Activity,若是在task中已经存在该Activity的实例,就调用它的onNewIntent方法,进入该task中。若是没有该Activity的实例,就建立一个新的task,把该Activity做为新task的根Activity。因此以singleTask启动的Activity不必定会新建立一个task。须要注意的是,即便Activity位于新的task里,按back键仍然会回到启动它的上一个Activity中,虽然它们不在同一个task里。
若是singleTask的Activity的taskAffinity和现有task的affinity相同,那就直接在现有的task里建立该Activity,因此以singleTask启动的Activity未必就是位于栈底的根Activity。
4.singleInstance
以这种模式启动的Activity本身独占一个task,若是已经有该Activity的实例,再次启动时会调它的onNewIntent。但以singleInstance启动的Activity按back的行为却与singleTask不一样。好比 A启动B,B是singleInstance,B再启动C,则B本身单独位于一个新的task中,A和C位于一个task中,则按back键时,从C不会退回到B,而是先退回到A,再按back键再退回到B。
注意,在代码中也能够设置Intent的flag来控制Activity的启动模式,代码中动态设置的比AndroidManifest.xml中静态写的Android:lauchMode优先级高。
5、Intent的flags
1.FLAG_ACTIVITY_NEW_TASK
为Activity新建立一个task,若是startActivity的context不是Activity,而是service或Application,那必定要加上这个flag。以这个flag启动Activity的行为跟launchMode为singleTask的一致。但并非每次都新建立一个task,把Activity放在里面,而是会先找是否已经有taskAffinity相同的task,若是有就把要启动Activity放在该task里,若是没有taskAffinity相同的task,才会新建一个task。
2.FLAG_ACTIVITY_SINGLE_TOP
做用同singleTop。
3.FLAG_ACTIVITY_CLEAR_TOP
启动Activity时,若是所在task里已经有该Activity的实例,则会清除在它上面全部的Activity。例如,task里的Activity启动关系是Aà Bà Cà D,而后在D启动B时,加上了FLAG_ACTIVITY_CLEAR_TOP标志,在B启动后task里就只有A和B了,C和D被清除了。若是B的launchMode是standard,那么当它收到Intent后,会先销毁掉原来B的实例,而后从新onCreate构建一个新的B;若是B是singleTask类型,那么会保留原有的B的实例,调用它的onNewIntent,传入新的Intent。
4.FLAG_ACTIVITY_CLEAR_TASK
启动Activity时,会清除所在task里其余全部的Activity。例如,task里的Activity启动关系是A à Bà C,在B启动C时,加上FLAG_ACTIVITY_CLEAR_TASK,那么在C启动后,task里就只剩C了,A、B被清除了。若是这个应用中只有这一个task,那么在C中按back键就退回到桌面了。
5.FLAG_ACTIVITY_REORDER_TO_FRONT
以该标志启动的Activity若是已经在task中存在,会被移动到栈顶,其余的Activity顺序不变。若是在task中不存在,则新建一个。例如,task里的Activity启动关系是A ->B ->C->D,在D启动B时,加上这个flag,则B就被移到了栈顶,task里就变成了A ->C ->D -> B了。若是B已经调了finish,但系统还没来得及把它从task中移出,这时以FLAG_ACTIVITY_REORDER_TO_FRONT方式启动B,则没法启动B。只有当B destroy之后才能够启动B。
6.FLAG_ACTIVITY_NO_HISTORY
这个FLAG可让启动的Activity一旦退出,就finish掉,再也不存在于栈中。例如,Activity的启动关系是A-> C->D,在B启动C时加上FLAG_ACTIVITY_NO_HISTORY,在C启动完D后,task里仍然是 A-> B->C->D的栈布局,C并没从栈中清除。当在D中按back键,不会退到C而是退到B,这时dumpsysactivity会发现task中没有C了,只有A和B,在D中按back键时,C就finish掉了。
7.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
以这个flag启动的Activity将不会在最近启动的应用列表中出现。
8.FLAG_ACTIVITY_FORWARD_RESULT
咱们用startActivityForResult和setResult在两个Activity之间传递数据,若是中间还隔着另外一个Activity,好比A -> B->C,要想在A和C之间用startActivityForResult和setResult的话,就要在B启动C时加上这个参数。也就是A正常的startActivityForResult启动B,B以FLAG_ACTIVITY_FORWARD_RESULT方式启动C,在C中setResult,这样当从C退回B,再退回到A,即C和B都finish后,A的onActivityResult会收到C中setResult传的值。
9.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
这个是从最近任务列表中启动Activity时由系统设置的,第三方应用不会用到这个标志,系统的SystemUI在最近任务列表中才会设这个标志。
10.FLAG_ACTIVITY_NO_ANIMATION
要启动Activity将不执行入场动画。
11.FLAG_ACTIVITY_TASK_ON_HOME
以这个flag启动的Activity所在的task将会位于Home所在的task之上,也就是说在这个Activity中按back键会回到home,而不是启动它的那个Activity。例如,A -> B,B的taskAffinity与A不一样,A启动B时同时加上了FLAG_ACTIVITY_TASK_ON_HOME和FLAG_ACTIVITY_NEW_TASK这两个标志,那么A和B位于不一样的task中,若是仅是以newtask方式启动B,那么即便B和A不在一个task中,那么在B中按back键仍是会退到A的,但加上了FLAG_ACTIVITY_TASK_ON_HOME后,按back键就退回到home了,此时A已经被移动到了后台。