《Android开发艺术探索》笔记1(Activity的生命周期和启动模式)

  • 1.1Activity的生命周期全面解析
    • 典型情况下的生命周期是指在有用户参与的情况下,Activity所经过的生命周期的改变;而异常情况下的生命周期是指Activity被系统回收或者由于当前设备的Configuration发生改变从而导致Activity被销毁重建。
    • 1.1.1典型情况下的生命周期分析
      • onCreate:表示Activity正在被创建,一般做一些初始化工作比如加载布局资源等
      • onRestart:表示Activity正在重新启动,当当前Activity从不可见变为可见状态时被调用
      • onStart:表示Activity正在被启动,即将开始,这是Activity已经可见了,但是没有出现在前台,还无法和用户交互
      • onResume:表示Activity已经可见了,并且出现在前台并开始活动
      • onPause:表示Activity正在停止,此时可以做一些存储数据、停止动画的工作,但是不能太耗时
      • onStop:表示Activity即将停止,可以稍微做一些稍微重量级的回收工作,同样不能太耗时
      • onDestory:表示Activity即将被销毁,可以做一些回收工作和最终的资源释放
      • 《Android开发艺术探索》笔记1(Activity的生命周期和启动模式)_第1张图片

      • 针对一个特定的Activity,第一次启动回调:onCreate->onStart->onResume
      • 当用户打开新的Activity或者切换到桌面的时候:onPause->onStop,如果新Activity采用透明主题,当前Activity不回调onStop
      • 当前用户再次回到原Activity,回调:onRestart->onStart->onResume
      • 当用户按Back键时,回调:onPause->onStop->onDestory
      • onCreate和onDestory是配对的,表示Activity的创建和销毁,并且只可能调用一次。从Activity是否可见来说,onStart和onStop是配对的,可能会调用多次。从Activity是否在前台来说,onResume和onPause是配对,也可能会调用多次
      • 问题:假设当前Activity为A,如果这是用户打开一个新的ActivityB,那么B的onStart和A的onPause那个先执行呢?
      • 旧的Activity先onPause,然后新的Activity再启动
    • 1.1.2异常情况下的生命周期分析
      • 资源相关的系统配置发生改变导致Activity被杀死并重新启动
        • 当系统配置发生改变后,Activity会被销毁,其onPause、onStop、onDestory均会被调用,由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。这个方法在onStop之前调用,和onPause没有既定的时序关系,onSaveInstanceState此方法只会出现在Activity被异常终止的情况下。Activity被重新创建之后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。区别onRestoreInstanceState一单被调用,其参数Bundle savedInstanceState一定有值,而onCreate不一定,需要进行判断是否为空。
      • 资源内存不足倒是低优先级的Activity被杀死
        • Activity按照优先级从高到低
          • 前台Activity--正在和用户交互的Activity,优先级最高
          • 可见但非前台Activity
          • 后台Activity--已经被暂停的Activity
        • 当系统内存不足时,系统会按照优先级去杀死目标Activity的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据
        • 如果我们没有在Activity的configChanges属性指定该选项,当配置发生改变后会导致Activity重新创建。如果指定configChanges,Activity不会重新创建,也不会调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,而是调用onConfigurationChanged方法
  • 1.2Activity的启动模式
    • 1.2.1Activity的LaunchMode
      • standard:标准模式,系统默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下的Activity的生命周期,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。
      • singleTop:栈顶复用模式,如果新的Activity已经位于任务栈的栈顶,那么此Activity不会重新被创建,同事它的onNewIntent方法会被回调,这个Activity的onCreate、onStart方法不会被系统调用,如果新Activity的实例已经存在但不在栈顶,那么新的Activity仍然会重新重建。
      • singleTask:栈内复用模式,这个是一个单实例模式,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,系统会回调其onNewIntent。singleTask默认有clearTop的效果,会使栈内当前Activity上面的Activity全部出栈。
      • singleInstance:单实例模式,加强的singleTask模式,此模式的Activity只能单独地位于一个任务栈中。
      • TaskAffinity:任务相关性,此参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需要的任务栈的名字就是应用的包名。也可以为每个Activity都单独制定TaskAffinity属性,属性值必须不能喝包名相同,否则就相当于没有指定。TaskAffinity主要和singleTask启动模式或者allowTaskReparenting属性配对使用。
      • 任务栈氛围前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
      • 当TaskAffinity和singleTask启动模式配对使用,它具有该模式的Activity的目前任务栈的模式,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。
      • 当TaskAffinity和AllReparenting结合的时候,AllReparenting属性为true,例如应用A启动应用B的ActivityC,此Activity会从A的任务栈里转移到B任务栈中。
      • Activity指定启动模式
        • 通过AndroidMenifest为Activity指定启动模式,无法为Activity设置FLAG_ACTIVITY_CLEAR_TOP标识,
          • android:name=".StandardActivity" 
          • android:launchMode="standard" > 
        • 通过Intent中设置标志位为Activity指定启动模式,优先级高于第一种,无法为Activity指定singleInstance模式
          • Intent i = new Intent(context, MainActivity.class);
          • i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
          • Intent.FLAG_ACTIVITY_CLEAR_TOP);
          • context.startActivity(i);
    • 1.2.2Activity的Flags
      • Intent.FLAG_ACTIVITY_NEW_TASK 为Activity指定singleTask启动模式,和在XML中的android:launchMode="singleTask"一样,如果指定taskAffinity的Activity存在,则移到栈顶,不存在则创建。默认情况下,一个应用中的所有activity具有相同的taskAffinity,即应用程序的包名
      • Intent.FLAG_ACTIVITY_SINGLE_TOP 为Activity指定singleTop启动模式,和在XML中的android:launchMode="singleTop"一样,如果已有则不创建,否则创建
      • Intent.FLAG_ACTIVITY_CLEAR_TOP 一般会和singleTask启动模式一起出现,被启动Activity的实例如果已经存在,那么系统就会调用它的onNewIntent同时此Activity上面的Activity会出栈,如果android:launchMode="standard",那么它自己也会出栈,然后再创建新的Activity实例并放入栈顶
      • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 具有这个标记的Activity不会出现在历史Activity的列表中,
      • Intent.FLAG_ACTIVITY_NO_HISTORY 新活动不会保留在历史栈中,一旦用户切换到其他页面,新活动会马上销毁。 旧活动的onActivityResult()方法永远不会被触发。
  • 1.3IntentFilter的匹配规则
    • 启动Activity分为两种,显示调用和隐式调用。显示调用需要明确地指定被启动对象的组件对象,包括包名和类名而隐式调用则不需要。隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息(包括action、category、data)
    • action的匹配规则
      • Intent中的action必须能够和过滤规则中的action匹配,即action的字符串值完全一样,action区分大小写。一个过滤规则可以有多个action,那么只有Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。如果Intent没有指定action,那么匹配失败。
    • category的匹配规则
      • 要求Intent中如果含有category,那么所有的category都必须和过滤规则中的一个category相同。如果没有category,可以匹配成功,一但有category,不管几个,每个都要能够和过滤规则中的任何一个category相同。
    • data的匹配规则
    • 如果过滤规则定义了data,那么Intent中必须也要定义可以匹配的data
    • data由两部分组成,mineType和URI。mineType指媒体类型,URI包含内容比较多
    • 结构:://:/[path]||
    • Scheme:URI的模式比如http、file、content,不设置则URI无效
    • Host:URI主机名,不指定则URI无效
    • Port:URI的端口号
    • Path、pathPattern、pathPrefix表述路径信息,分别指完整路径信息、通配符、路径前缀信息
    • 匹配规则要求Intent必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data。完全匹配指过滤规则中出现的data部分也出现在Intent中的data中。

你可能感兴趣的:(android)