本文为笔者在学习《Android开发艺术探索》第一章Activity的生命周期和启动模式时,对认为重要的知识点进行提取和整理。本文不会涉及具体、详细的代码,如有需要,可自行查阅《Android开发艺术探索》。
目录
-
典型情况下的生命周期:
-
生命周期方法:
- onCreate()、onRestart()、onStart()、onResume();
- onPause()、onStop()、onDestroy();
-
常见场景下的调用顺序:
场景 调用顺序 启动 onCreate() --> onStart() --> onResume() 点击Home键/任务键/屏幕休眠 onPause() --> onStop() 返回app onRestart() --> onStart() --> onResume() 从A 跳转到第二个Activity——B A onPause() --> B onCreate() --> B onStart() --> B onResume() --> A onStop() 从B返回到A B onPause() --> A onRestart() --> A onStart() --> A onResume() --> B onStop() 退出应用 onPause() --> onStop() --> onDestroy() -
生命周期方法介绍:
方法 状态 任务 注意 onCreate 正在创建 加载界面布局资源、初始化所需数据 传参Bundle为上次被异常情况销毁时保存的状态信息 onRestart 正在重新启动。从不可见重新变为可见状态 。 onStart 正在启动。可见、不在前台,无法和用户交互。 onResume 已经可见、在前台并开始活动、可和用户交互。 onPause 正在停止。可见、在前台、不可和用户交互 轻量级的存储数据、停止动画等操作 启动新Activity,会先调用旧Activity的onPause onStop 即将停止。可见、不在前台。 稍微重量级的回收工作 onDestroy 即将被销毁。不可见。 回收工作、资源释放
-
异常情况下的生命周期:
-
生命周期方法:
方法 作用 例子 注意 onSaveInstanceState() 保存当前Activity的状态 文本框中输入的数据、
ListView滚动的位置
和onPause()没有既定的时序关系; onRestoreInstanceState() 恢复状态 系统可通过该方法和onCreate来判断Activity是否被重建 -
异常情况:
情况 例子 调用顺序 注意 资源相关系统配置改变,
Activity被杀死并重新创建
屏幕发生旋转 onPause() --> onSaveInstanceState() --> onStop() --> onCreate -->
onStart() --> onRestoreInstanceState() -->
onResume()
资源内存不足,低优先级Activity被杀死 同上 Activity优先级从高到低 高 前台Activity 正在和用户交互 中 可见、非前台 弹出对话框后的Activity 低 后台Activity 已经被暂停的Activity,如执行了onStop -
避免Activity被重新创建:
- 给AndroidManifest,xml中的Activity指定configChanges属性: "orientation | screenSize"
-
启动模式
-
设置Activity启动模式:
- 通过AndroidMenifest:android:launchMode="singleTask"
- 通过Intent中设置标志位:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
四种启动模式:
启动模式 翻译 意义 注意 standard 标准模式 每次启动一个Activity都会重新创建一个实例 运行在启动它的那个Activity所在的栈中,因此使用ApplicationContext启动标准模式的Activity会报错。
解决办法为指定FLAG_ACTIVITY_NEW_TASK标记位,启动时会创建任务栈。
singleTop 栈顶复用模式 新Activity位于任务栈栈顶,则不会重新创建。
onNewIntent方法会被回调,可从此方法的参数中取出当前请求的信息。
该Activity的onCreate、onStart不会被系统调用;
若新Activity的实例不位于栈顶,则Activity会被重建;
singleTask 栈内复用模式 一种单实例模式,只要Activity在一个栈中存在,那么多次启动都不会重新创建 系统也会回调其onNewIntent。
具有clearTop效果,会导致栈内所有在启动Activity上的其它Activity全部出栈;
singleInstance 单实例模式 加强的singleTask模式;
只能单独地位于一个任务栈中。
-
任务栈:
-
TaskAffinity (任务相关性):这个参数标识了一个Activity所需要的任务栈的名字。 默认情况下,所有Activity所需的任务栈的名字为应用的包名;
-
指定任务栈名字:TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用,其他情况下没有意义;
-
分为前台任务栈和后台任务栈:后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调用前台;
-
使用:android:taskAffinity="包名"
-
-
常用标志位:
标志位 说明 FLAG_ACTIVITY_NEW_TASK 为Activity指定“singleTask”启动模式 FLAG_ACTIVITY_SINGLE_TOP 为Activity指定“singleTop”启动模式 FLAG_ACTIVITY_CLEAR_TOP 启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。
该模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 该标记的Activity不会出现在历史Activity的列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。
等同于 android:excludeFromRecents="true"
-
IntentFilter的匹配规则
-
启动Activity的调用方式:
- 显式调用:需明确指定被启动对象的组件信息,包括包名和类名,如new Intent(MainActivity.this, TestActivity.class);
- 隐式调用:需Intent能够同时匹配目标组件的某个IntentFilter中所设置的过滤信息(action、category、data);
-
各种属性的匹配规则:
- action:Intent中的action存在 且 必须和过滤规则中的其中一个action相同,区分大小写;
- category:
- Intent中如果含有(即可以没有)category,那么所有的category都必须和过滤规则中的其中一个category相同。
- 可以没有的原因:系统在调用startActivity或则startActivityForResult的时候会默认加上"android.intent.category.DEFAULT",但必须在intent-filter中指定"android.intent.category.DEFAULT"
- data:
- 如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data;
- 由mimeType(媒体类型)和 URI 组成:
- mimeType:如image/jpeg、video/*等,开表示图片、文本、视频等不同的媒体格式;
- URI:<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPaattern>]
- 若为mimeType指定了 "image/*",那么URI的scheme默认为content和file;
- 为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法彼此会清除对方的值。
-
隐式调用前的判断:
- 采用 PackageManager的resolveActivity方法 或则 Intent的resolveActivity方法,如果它们找不到匹配的Activity就会返回null,通过判断返回值可以规避错误;