《Android开发艺术探索》总结:Activity的生命周期和启动模式

第1章 Activity的生命周期和启动模式

1.1 Activity的生命周期全面分析

1.1.1 典型情况下的生命周期分析

img

1.七个生命周期

1.onCreate():

  • 状态:Activity 正在创建
  • 任务:做初始化工作,如setViewContent界面资源、初始化数据

2.onStart():

  • 状态:Activity 正在启动,这时Activity 可见但不在前台,无法和用户交互。

3.onResume():

  • 状态:Activity 获得焦点,此时Activity 可见且在前台并开始活动。

4.onPause():

  • 状态: Activity 正在停止
  • 任务:可做 数据存储、停止动画等操作。
  • 注意:
    • Activity切换时,旧Activity的onPause会先执行,然后才会启动新的Activity的onResume。
    • Activity在处于onPause、onStop、onDestroy状态下,系统都可以销毁该Activity所在进程,所以我们在处理一些要保存的数据时,必须在onPause方法中进行,因为onStop和onDestroy方法不一定会被调用。

5.onStop():

  • 状态:Activity 即将停止
  • 任务:可做稍微重量级回收工作,如取消网络连接、注销广播接收器等,但同样不能太耗时。
  • 注意:如果新Activity是透明主题时,旧Activity不会进入onStop方法,因为旧Activity依然可见。

6.onDestroy():

  • 状态:Activity 即将销毁
  • 任务:做回收工作和最终的资源释放

7.onRestart():

  • 状态:Activity 重新启动,Activity由后台切换到前台,由不可见到可见。
2.附加说明
  • onStart和onResume都表示Activity可见了,但onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的。
  • 旧的Activity的onPause必须先执行完,新的Activity的onResume才会执行。
  • 当用户打开一个新的Activity或者切换回桌面的时候,回调如下:onPause->onStop;但如果新Activity采用了透明主题,则当前Activity不会回调onStop(因为它依然可见)。

1.1.2 异常情况下的生命周期分析

1. 系统配置变化导致Activity销毁重建
  • 例如Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,Activity就会被销毁并重新创建
  • 在异常情况下系统会在onStop之前调用onSaveInstanceState来保存状态。Activity重新创建后,会在onStart之后调用onRestoreInstanceState来恢复之前保存的数据。
  • 保存数据的流程: Activity被意外终止,调用onSaveIntanceState保存数据-> Activity委托Window,Window委托它上面的顶级容器一个ViewGroup( 可能是DecorView) 。然后顶层容器在通知所有子元素来保存数据。这是一种委托思想,Android中类似的还有:View绘制过程、事件分发等。
  • 系统只在Activity异常终止的时候才会调用 onSaveInstanceState 和onRestoreInstanceState 方法。其他情况不会触发。
2 资源内存不足导致低优先级的Activity被回收
  • Activity优先级大小排序:
    • 前台可见Activity>前台可见不可交互Activity(前台Activity弹出Dialog,导致Activity无法和用户直接交互)>后台Activity
  • 如果一个进程没有四大组件,那么将很快被系统杀死。因此,后台工作最好放入service中。
  • android:configChanges=”orientation” 在manifest中指定 configChanges 在系统配置变化后不重新创建Activity,也不会执行 onSaveInstanceState 和onRestoreInstanceState 方法,而是调用 onConfigurationChnaged 方法。
  • configChanges 一般常用三个选项:
    • locale 系统语言变化
    • keyborardHidden 键盘的可访问性发生了变化,比如用户调出了键盘
    • orientation 屏幕方向变化

1.2 Activity的启动模式

1.2.1 Activity的LaunchMode

Android使用栈来管理Activity,有四种启动模式。

  1. standard(标准模式)

    • 每次启动都会重新创建一个实例,不管这个Activity在栈中是否已经存在。谁启动了这个Activity,那么Activity就运行在启动它的那个Activity所在的栈中。
    • 用ApplicationContext去启动Activity时会报错,原因是非Activity的Context没有任务栈。解决办法是为待启动Activity指定FLAG_ACTIVITY_NEW_TASH标志位,这样就会为它创建一个新的任务栈。
  2. singleTop(栈顶复用模式)

    • 如果新Activity位于任务栈的栈顶,那么此Activity不会被重新创建,同时回调 onNewIntent 方法
    • onCreate和onStart方法不会被执行。
  3. singleTask(栈内复用模式)

    • 这是一种单实例模式。如果不存在activity所需要的任务栈,则创建一个新任务栈和新Activity实例;如果存在所需要的任务栈,不存在实例,则新创建一个Activity实例;如果存在所需要的任务栈和实例,则不创建,调用onNewIntent方法。同时使该Activity实例之上的所有Activity出栈。
  4. singleIntance(单实例模式)

    • 单实例模式。具有singleTask模式的所有特性,具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例

    • 使用场景:因为这种模式下有一个单独的返回栈来管理这个活动,不管哪个应用程序来访问这个互动,都共用的同一个返回栈,所以可以多个程序共享活动

  • Activity的启动模式可以通过AndroidMenifest为其指定启动模式
<activity
      android:name=".MainActivity"
      android:launchMode="singleTask" />

还可以通过在Intent中设置标记位来为Activity指定启动模式

    Intent intent = new Intent(this,MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

两种方法都可以为Activity指定启动模式,但还是有区别。第二种方式的优先级高于第一种,如果都设置了只有第二种会生效。第一种方式无法直接为Activity设置FLAG_ACTIVITY_CLEAR_TOP标记,而第二种方式无法为Activity指定singleInstance模式。

1.2.2 Activity的Flags

  • FLAG_ACTIVITY_NEW_TASK
    为Activity指定“singleTask”启动模式,其效果和xml中指定该启动模式相同。

  • FLAG_ACTIVITY_SINGLE_TOP
    为Activity指定“singleTop”启动模式,其效果和xml中指定该启动模式相同。

  • FLAG_ACTIVITY_CLEAR_TOP
    具有此标记位的Activity,当他启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。这个模式一般与FLAG_ACTIVITY_NEW_TASK配合使用,singleTask启动模式默认具有此标记为的效果。

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    具有这个标记为的Activity不会出现在历史Activity的列表中,当某些情况不希望用户通过历史列表回到我们Activity的时候这边标记比较有用。等同于在XML中指定Activity的属性android:excludeFromRecents=“true”。

1.3 IntentFilter的匹配规则

启动Activity分为两种,显式调用(明确地指定被启动对象的组件信息,包括包名和类名)和隐式调用(不需要明确指定组件信息,需要Intent能匹配上目标组件的IntentFilter中所设置的过滤信息)。IntentFilter的过滤信息有action、category、data。为了匹配过滤列表,需同时匹配过滤列表中的action、category、data信息,否则匹配失败;一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应的Activity。

  1. action的匹配规则
    一个过滤规则中可以有多个action,Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。如果Intent没有指定action,那么匹配失败。action区分大小写。
  2. category的匹配规则
    Intent中可以没有category;如果有,不管有几个,每个都要能和过滤规则中的任何一个category相同;如果没有,依然可以匹配成功,因为如果没有指定category,在调用startActivity或startActivityForResult时系统会默认加上“android.intent.category.DEFAULT”这个category。同时为了我们的Activity能够支持隐式调用,就必须要在intent-filter中指定“android.intent.category.DEFAULT”这个category。
  3. data的匹配规则
    data的匹配规则和action类似,如果过滤规则定义了data,那么Intent必须定义可匹配的data。
    先介绍一下data的结构(有些复杂)
 <data android:scheme="string"
           android:host="string"
           android:port="string"
           android:path="string"
           android:pathPattern="string"
           android:pathPrefix="string"
           android:mimeType="string" 

data由两部分组成,mimeType和URI。mimeType是指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等不同的媒体格式,而URI中包含的数据就比较多了,下面是URI的结构

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<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:URI中的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的。
Path、pathPattern和pathPrefix:这三个参数都是表示路径信息;其中path表示完整的路径信息;pathPattern也表示完整路径信息,但是它里面可以包含通配符“”,“”表示0个或多个任意字符;pathPrefix表示路径的前缀信息。

data的匹配规则

  1. 要求Intent中必须含有data数据,并且data数据能够完全匹配过滤规则中的某一个data;这里的完全匹配是指过滤规则中出现的data部分也出现在了Intent中的data中。
  2. 如果没有指定URI,是有默认值的,URI的默认值为content和file。也就是说,虽然没有指定URI,但Intent中的URI部分的schema必须为content或者file才能匹配。
  3. 如果要为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法都会清除对方的值。

补充:

  1. 当我们隐式启动一个Activity的时候,可以做一下判断,看是否能匹配到我们的隐式Intent,如果不做判断没找到对应的Activity系统就会抛出android.content.ActivityNotFoundException异常。采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果找不到匹配的Activity就会返回null,我们通过判断返回值就可以规避上述错误了。
  2. 在intent-filter中声明了这个category的Activity,才可以接收隐式意图。
  3. 有一类action和category的共同作用是标明这是一个入口Activity,并且会出现在系统的应用列表中,少一个都没有任何意义,也不会出现在系统的应用列表中。
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值