开发艺术探索之Activity

接下来的几天学习任老师的《Android开发艺术探索》,这里做相关的笔记(参考:文章)(同样,作为学习书籍,文章定义为转载)

  • 生命周期全面分析
    • 典型情况下的声明周期
    • 异常情况下的生命周期(两种情况)
  • 四种启动模式
    • 启动方式1:LaunchMode
    • 启动方式2:Flags(不常用)
  • IntentFilter匹配规则

 

生命周期全面分析

典型情况下的生命周期

生命周期的各阶段

完整生命周期Activity在onCreate()和onDestroy()之间所经历的。
在onCreate()中完成各初始化操作,在onDestroy()中释放资源。
可见生命周期Activity在onStart()和onStop()之间所经历的。
活动对于用户是可见的,但仍无法与用户进行交互。
前台生命周期Activity在onResume()和onPause()之间所经历的。
活动可见且可交互。

正常情况下,Activity会经历以下生命周期

生命周期状态任务备注
onCreateActivity 正在创建做初始化工作,如setContentView界面资源、初始化数据此方法的传参Bundle为该Activity上次被异常情况销毁时保存的状态信息
onStartActivity 正在启动(null)这时Activity 可见但不在前台,无法和用户交互。
onResumeActivity 获得焦点(null)此时Activity 可见且在前台并开始活动
onPauseActivity 正在停止可做 数据存储、停止动画等操作Activity切换时,旧Activity的onPause会先执行,然后才会启动新的Activity
onStopActivity 即将停止可做稍微重量级回收工作,如取消网络连接、注销广播接收器等新Activity是透明主题或是dialoge时,旧Activity都不会走onStop
onDestoryActivity 即将销毁回收工作、资源释放(null)
onRestartActivity 重新启动(null)Activity由后台切换到前台,由不可见到可见

常见情况的生命周期切换过程

动作切换过程
启动Activity1

onCreate()-->onStart()-->onResume()

在Activity1打开一个新Activity2

Activity1的onPause() -->Activity2的onCreate()-->onStart()-->onResume()-->Activity1的onStop()

Activity2返回到Activity1

Activity2的onPause()-->Activity1的onRestart()-->onStart()-->onResume()-->Activity2的onStop()-->onDestory()

Activity1上弹出对话框Activity2

Activity1的onPause()-->Activity2的onCreate()-->onStart()-->onResume()

关闭屏幕/按Home键

Activity2的onPause()-->onStop()-->Activity1的onStop()

点亮屏幕/回到前台

Activity2的onRestart()-->onStart()-->Activity1的onRestart()-->onStart()-->Activity2的onResume()

关闭对话框Activity2

Activity2的onPause()-->Activity1的onResume()-->Activity2的onStop()-->onDestroy()

异常情况下的生命周期(两种情况)

情况一:由于资源相关配置发生改变,导致Activity被杀死和重新创建

例如屏幕发生旋转:当竖屏切换到横屏时,会先调用onSaveInstanceState来保存切换时的数据,接着销毁当前的Activity,然后重新创建一个Activity,再调用onRestoreInstanceState恢复数据。(文本框数据、listView位置等相关信息系统会自动帮我们恢复,我们也可以重写)(onSaveInstanceState方法只会在Activity异常终止的情况下调用

  • 相应的生命周期为onSaveInstanceState(此方法也可能在onPause后调用)-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume
  • 可通过onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)来判断Activity是否被重建,并取出数据进行恢复。但需要注意的是,在onCreate取出数据时一定要先判断savedInstanceState是否为空。(谷歌推荐使用onRestoreInstanceState进行数据恢复。)

  • onSaveInstanceState与onPause的区别:前者适用于对临时性状态的保存,而后者适用于对数据的持久化保存。)
  • 为了避免由于配置改变导致Activity重建,可在AndroidManifest.xml中对应的Activity中设置android:configChanges="orientation|screenSize"。此时再次旋转屏幕时,该Activity不会被系统杀死和重建,只会调用onConfigurationChanged。因此,当配置程序需要响应配置改变,指定configChanges属性,重写onConfigurationChanged方法即可。

情况二:由于系统资源不足,导致优先级低的Activity被回收

Activity优先级排序:前台可见Activity>前台可见不可交互Activity(前台的Activity弹出了Dialog)>后台Activity(用户按下Home键、切换到其他应用)

当系统内存不足时,会按照Activity优先级从低到高去杀死目标Activity所在的进程,并通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。如果一个进程没有四大组件在执行,那么这个进程将很快被系统杀死。

四种启动模式

设置Activity启动模式的方法(两种)

  • 在AndroidManifest.xml中给对应的Activity设定属性:  android:launchMode="standard|singleInstance|single Task|singleTop"。
  • 通过标记位设定,方法是intent.addFlags(Intent.xxx)

优先级上,第二种优先级高于第一种,同时存在时,以第二种为准。(第一种无法直接为Activity设定FLAG_ACTIVITY_SINGLE_TOP,第二种无法为Activity指定singleInstance模式)

Activity的四种LaunchMode

英文名称名称含义备注使用实例
standard标准模式、默认模式每次启动一个Activity就会创建一个新的实例。使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈

情况:A-->A-->A:

返回时:A-->A-->A-->退出

 

singleTop栈顶复用模式如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调onNewIntent(intent)方法。 

情况:A-->B-->A

返回时:A-->B-->A-->退出

 

singleTask栈内复用模式只要该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity放进去;如果存在,就会创建到已经存在的栈中。(若所需要的栈内存在实例,则会调用该实例的onNewIintent,并把该实例上面的Activity全部出栈)

情况1:A-->B-->A

返回时:A-->退出

情况2:A-->B-->B

返回时:B-->A-->退出

 

singleInstance单实例模式 (可以理解为加强版的singleTask)具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。  

常用的可设定Activity启动模式的标记位(不常用)

  • FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式。
  • FLAG_ACTIVITY_NEW_TASK :对应singleTask模式。
  • FLAG_ACTIVITY_CLEAR_TOP:当相应的Activity启动时,同一个任务栈中所有位于它上面的Activity都要出栈。(一般配合FLAG_ACTIVITY_NEW_TASK使用。)
  • FLAG_ACTIVITY_FROM_RECENTS:具有这个标记的Activity不会出现在历史Activity的列表中(当某些情况下我们不希望用户通过历史列表回到我们的Activity'的时候使用这个标记比较有用。它等同于在xml指定Activity的属性:android:excludeFromRecents=“true”)

IntentFilter匹配规则

因为启动Activity可以显示调用和隐式调用,显示调用只需要明确指定被启动对象的组建信息(包名和类名),隐式调用需要Intetn能够匹配目标组件的IntenFilter中所设置的过滤信息。

  • 一个intent只有同时匹配某个Activity的intent-filter中的action、category、data才算完全匹配,才能启动该Activity。
  •  一个Activity可以有多个 intent-filter,一个 intent只要成功匹配任意一组 intent-filter,就可以启动该Activity。
  • 可以用PackageManager的resolveActivity方法或者Intent的resolveActivity方法判断是否有Activity匹配该隐式Intent。

action匹配规则:

  • 要求intent中的action 存在且必须和intent-filter中的其中一个 action相同。
  • 区分大小写。

 category匹配规则:

  • intent中的category可以不存在,这是因为此时系统给该Activity 默认加上了< category android:name="android.intent.category.DEAFAULT" />属性值。
  • 除上述情况外,有其他category,则要求intent中的category和intent-filter中的所有category 相同。

data匹配规则:

  • 如果intent-filter中有定义data,那么Intent中也必须也要定义data。
  • data主要由mimeType(媒体类型)和URI组成。在匹配时通过intent.setDataAndType(Uri data, String type)方法对date进行设置。
  • 要求和action相似:如果没有指定URI,默认值为content和file; 有多组data规则时,匹配其中一组即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值