Activity笔记(一) android


Activity的生命周期和启动模式(一)

该模块主要是讲Activity的启动模式以及IntentFilter的匹配规则:

Questions:

  1. 为什么KP2中这种情况会发生?

  2. KP2中旧的onStop什么时候调用呢? 目前看来是新的activity展示在前台之后会调用(还是说另开线程调用,所以与新的无关?)

Knowledge points:

  1. Activity,Window,Dialog, Toast为四个能够让用户见到的界面。

  2. 如果新的activity采用了透明主题,那么当用户打开新的activity或者返回桌面时,改Activity不会调用onStop。

  3. onStart、onStop和onResume、onPause的区别在于前者是从Activity是否可见这个角度进行回调,而后者是Activity是否处于前台这个角度进行回调的。

  4. 旧Activity下先pause新的才会执行生命周期

  5. 如果一个进程 中没有四大组件在执行,那么这个进程将很快被系统杀死,因此,一些后台工作不适合脱 离四大组件而独自运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放 入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。

  6. 用ApplicationContext无法启动standard模式的activity,但是如果为启动的Activity指定一个FLAG_ACTIVITY_NEW_TASK,这时候Activity就会以singleTask模式启动。

 

生命周期:

(1) onCreate:表示Activity正在被创建,这是生命周期的第一个方法。在这个方法中, 我们可以做一些初始化工作,比如调用setContentView去加载界面布局资源、初始化Activity 所需数据等。

(2) onRestart:表示Activity正在重新启动。一般情况下,当当前Activity从不可见重 新变为可见状态时,onRestart就会被调用。这种情形一般是用户行为所导致的,比如用户 按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停, 也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。

(3) onStart:表示Activity正在被启动,即将开始,这时Activity已经可见了,但是还 没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity经显示出来了, 但是我们还看不到。

(4) onResume:表示Activity已经可见了,并且出现在前台并开始活动。要注意这个 和onStart的对比,onStart和onResume都表示Activity己经可见,但是onStart的时候Activity 还在后台,onResume的时候Activity才显示到前台。

(5) onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特 殊情况下,如果这个时候快速地再回到当前Activity,那么onResume会被调用。笔者的理 解是,这种情况属于极端情况,用户操作很难重现这一场景。此时可以做一些存储数据、 停止动画等工作,但是注意不能太耗时,因为这会影响到新Activity的显示,onPause必须 先执行完,新Activity的onResume才会执行

(6) onStop:表Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。

(7) onDestroy:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调, 在这里,我们可以做一些冋收工作和最终的资源释放。

异常情况的生命周期分析:

  1. 系统配置改变的情况下(比如横屏)Activity被杀死并重新创建:

    当系统配置发生改变后,Activity会被销毁,其onPause> onStop、onDestroy均会被调用,系统会调用onSavelnstanceState来保存当前 Activity的状态,调用时机是在onStop之前,它和onPause没有既定的时序关系,,同时,我们要知道,在onSavelnstanceState和onRestorelnstanceState方法中,系统自动 为我们做了一定的恢复工作。当Activity在异常情况下需要重新创建时,系统会默认为我 们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动的位置等(每个View都有这两个方法)

    关于保存和恢复View层次结构,系统的工作流程是这样的:首先Activity被意外终止 时,Activity会调用onSavelnstanceState去保存数据,然后Activity会委托Window去保存 数据,接着Window再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup, 一般来说它很可能是DecorView,最后顶层容器再去一一通知它的子元素来保存数据,这 样整个数据保存过程就完成了。可以发现,这是一种典型的委托思想,上层委托下层、父 容器委托子元素去处理一件事情,这种思想在Android中有很多应用,比如View的绘制过 程、事件分发等都是采用类似的思想。

    onRestorelnstanceState 或者 onCreate,二者的区别是:onRestorelnstanceState 一旦被调用, 其参数Bundle savedlnstanceState 一定是有值的,我们不用额外地判断是否为空;但是 onCreate 不行,onCreate 如果是正常启动的话,其参数 Bundle savedlnstanceState 为 null, 所以必须要额外判断。这两个方法我们选择任意一个都可以进行数据恢复,但是官方文 档的建议是釆用onRestorelnstanceState去恢复数据。

  2. 资源内存不足导致低优先级的Activity被杀死

    Activity按照优先级从高到低,可以分为如下三种:

    (1)前台Activity 正在和用户交互的Activity,优先级最高。

    (2)可见但非前台Activity比如Activity中弹出了一个对话框,导致Activity可见

    但是位于后台无法和用户直接交互。

    (3)后台Activity 已经被暂停的Activity,比如执行了 onStop.优先级最低

 

如果不希望activity在系统配置变更的时候重新创建

我们不想系统重新创建Activity, 可以给Activity指定configChanges属性。比如不想让Activity在屏幕旋转的时候重新创建, 就可以给configChanges属性添加orientation这个值

image-20220407101855979

Activity的启动模式

  1. standard 重新创建一个activity。

  2. singleTop

    栈顶复用,onNewIntent会被回调。

  3. singleTask

    栈内复用,onNewIntent会被回调。默认为clearTop。会调用onResume。

  4. singleInstance

指定启动模式

  1. 通过AndroidMenifest指定,无法直接设定FLAG_ACTIVITY_CLEAR_TOP

  2. 在Intent中指定(优先级比1高),无法设定singleInstance

END 2022/4/7 1h20min

 

Activity常见的标志位以及匹配规则

Questions

Knowledge points

  1. 标记位可以

    • 设定 Activity的启动模式。

    • 影响Activity的运行状态等。

  2. 一个个Activity中可以有多个intent-filter, 一个Intent要能匹配 任何一组intent-filter即可成功启动对应的Activity。

IntentFilter的匹配规则

IntentFilter中过滤的信息有action、category、data。

Action的匹配规则

Action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配,和过滤规则中任何一个action值匹配就可以,这里 说的匹配是指action的字符串值完全一样。(区分大小写)。

必须有一个action且匹配。

category的匹配规则

Intent中出现的category必须完全匹配每一个intent-filter组其中一个。

可以没有category。

系统调用时会加上默认的category。

data的匹配规则

data的结构:
 <data android:scheme="String"
   android:host="String"
   android:port="String"
   android:path="String"
   android:pathPattern="String"
   android:pathPrefix="String"
       android:mimeType="String"/>

由两部分组成,一部分是mimeType,一部分是URI

  • mimeType: 指媒体类型,比如image/jpeg、 audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式。

  • URI:

    <scheme>://<host>:<port>/[<path>I<pathPrefix>I<pathPattern>]

    例如:content://com.example.project:200/folder/subfolder/etc

    http://www.baidu.com:80/search/info

Scheme: URI的模式,比如http、file、content等,如果URI中没有指定scheme,那 么整个URI的其他参数无效,这也意味着URI是无效的。

Host: URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI中的其 他参数无效,这也意味着URI是无效的。

Port: UR1中的端口号,比如80,仅当URI中指定了 scheme和host参数的时候port 参数才是有意义的。

Path, pathPattem和pathPrefix:这三个参数表述路径信息,其中path表示完整的路径 信息;pathPattem也表示完整的路径信息,但是它里面可以包含通配符“”表示0 个或多个任意字符,需要注意的是,由于正则表达式的规范,如果想表示真实的字符串, 那么“*”要写成“//”,”//”要写成“////”; pathPrefix表示路径的前缀信息。

匹配规则
  1. data的匹配 规则和action类似,它也要求Intent中必须含有data数据,并且data数据能够完全匹配过 滤规则中的某一个data.这里的完全匹配是指过滤规则中出现的data部分也出现在了 Intent 中的data中。

  2. 果要为Intent指定完整的data,必须要调用setDataAndType方法,不能先调 用setData再调用setType,因为这两个方法彼此会清除对方的值。

 

判断是否能够隐式启动Activity

  1. 采用 PackageManager 的 resolveActivity 方法或者 Intent 的 resolveActivity 方法,如 果它们找不到匹配的Activity就会返回null,我们通过判断返回值就可以规避上述错误了。

  2. 另外,PackageManager 还提供了 querylntentActivities 方法,这个方法和 resolveActivity 方 法不同的是:它不是返回最佳匹配的Activity信息而是返回所有成功匹配的Activity信息。我们要使用MATCH_ DEFAULT_ONLY这个标记位,这个标记位的含义是仅仅匹配那些在intent-filter中声明了 <category android:name=”android.intent.category.DEFAULT/>这个 category 的 Activity。 使用 这个标记位的意义在于,只要上述两个方法不返回null,那么startActivity -定可以成功。 如果不用这个标记位,就可以把intent-filter中category不含DEFAULT的那些Activity给 匹配出来,从而导致startActivity可能失败。因为不含有DEFAULT的intentFilter无法接受隐式intent。

  3.  

原创文章,作者:,如若转载,请注明出处:https://blog.ytso.com/272512.html

(0)
上一篇 2022年7月9日
下一篇 2022年7月9日

相关推荐

发表回复

登录后才能评论