好久没写Android代码了,手动写写文章总结热热手,让我还不至于以往我的Android小老弟。Android 是一个被设计的极其艺术性的系统,秉承着“人人生而平等”的Android系统,也是让人很难忘却的呢。
遵循着前人的脚步,我老实的回顾着Activity中我所能记得的尽可能多的知识,期盼着能捋出一个清晰的思路,犹如神助般指点江山。可惜的是,我的脑子里出现的都是一些零零碎碎的琐碎知识,并不成一个体系。如此这般,我才觉得,原来我这几年的Android生涯仿佛是喂了狗了~于是乎,我捡了个软骨头——毫无新意的启动与配置。
什么是Android

技术的价值在于其不断的创造力,而Android的兼职则在于便捷的使用上,就客户而言,感知到的才是价值,感知到的才是Android。而能让用户感知到的恰恰就是Activity,可见Activity的重要性。对于Activity的生命周期,老生长谈,我不想再一次次来解释,直接放图,显得更为直观。

异常中止
资源相关的系统配置发生改变
如屏幕尺寸改变、翻转、语言环境切换等均会导致Activity的销毁并重新创建,在此创建过程中,activity会在销毁前通过onSaveInstanceState方法用于保存Activity的状态值,并在重启时通过onRestoreInstanceState方法回复状态。
常见的系统配置导致Activity重新创建的如下:
属性 | 含义 |
mcc | SIM卡唯一标识中的国家代码,中国为460 |
mnc | SIM卡唯一标识中的运营商代码 |
local | 系统语言环境的改变 |
touchscreen | 触摸屏改变 |
keyboard | 键盘类型发生改变 |
keyboardHidden | 键盘的可访问性发生改变 |
navigation | 系统导航方式改变,如虚拟按键和全面屏 |
screenLayout | 屏幕布局发生改变 |
fontScale | 系统字体缩放比例发生改变 |
uiMode | 用户界面模式发生改变(夜间模式) |
orientation | 屏幕方向发生改变,常用,如屏幕翻转 |
screenSize | 屏幕尺寸发生改变 |
smallestScreenSize | 屏幕物理尺寸发生改变,如TV扩屏 |
layoutDirection | 布局方向发生改变 |
....
// 回复状态
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
currentPageIndex = savedInstanceState?.getInt(POSITION) ?: 0
if (currentPageIndex in 0..1)
viewModel.position.postValue(currentPageIndex)
super.onRestoreInstanceState(savedInstanceState)
}
// 保存状态
override fun onSaveInstanceState(outState: Bundle) {
outState.let {
it.putInt(POSITION, currentPageIndex)
searchFragment?.apply {
supportFragmentManager.putFragment(
it,
FRAGMENT_KEY_SEARCH, this
)
}
resultFragment?.apply {
supportFragmentManager.putFragment(
it,
FRAGMENT_KEY_RESULT, this
)
}
}
super.onSaveInstanceState(outState)
}
资源不足导致低优先级Activity被杀死
这个比较常见于系统内存不足时,比如我们开了好几个应用,每个应用的Activity栈中都存放了好几个Activity、服务广播杂七杂八一堆,这时候系统就会根据应用的优先级、组件的优先级有选择的先释放部分。其优先级类似进程的优先级。
如下,优先级由高到低:
- 前台Activity :当前正在操作,获取焦点的界面
- 可视Activity:处于onPause,但界面可见,如界面覆盖,操作指引类的模板底部Activity.
- 后台Activity:即是处于栈内,但不可见的Activity,此类Activity的优先级最低,优先释放。
启动模式
都知道Activity的管理是AMS通过栈的结构对其进行管理的,为了适应于不同场景AMS为Activity设计了如下四种结构:
- standard模式
标准模式,是属于系统默认的模式,默认activity通过压栈的方式存储,单栈存储多个Activity,并有着栈的特性:先进后出。
- singleTop模式
栈顶复用模式,这也是比较常见的一种方式,设置为这种模式的Acitity,在启动时如当前栈顶是该Activity的一个实例对象,将不在对其进行实例化启动。
- singleTask模式
栈内复用模式,该模式下的Activity,若启动一个Activity 的实例时,当前栈以存在该实例对象,则将其上的Activity出栈处理,复用已存在的Activity。
- singleInstance模式
单实例模式,这可以说是singleTask模式的加强版,singleTask的复用是在某一个栈内,而singleInstance是在一个App内,独享一个Activity的栈,且栈内只有其一个实例对象。
标志位
说到Activity就不得不说标志位,Activity的使用过程配合标志位往往能获得意外的收获,如我们可以通过标志位的方式如上方一般实现不同模式的Activity创建,以下为常用的标志位
public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304;
public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768;
public static final int FLAG_ACTIVITY_CLEAR_TOP = 67108864;
/** @deprecated */
@Deprecated
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 524288;
public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 8388608;
public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432;
public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576;
public static final int FLAG_ACTIVITY_LAUNCH_ADJACENT = 4096;
public static final int FLAG_ACTIVITY_MATCH_EXTERNAL = 2048;
public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728;
public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 524288;
public static final int FLAG_ACTIVITY_NEW_TASK = 268435456;
public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536;
public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824;
public static final int FLAG_ACTIVITY_NO_USER_ACTION = 262144;
public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 16777216;
public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 131072;
public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 2097152;
public static final int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 8192;
public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912;
public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384;
public static final int FLAG_DEBUG_LOG_RESOLUTION = 8;
public static final int FLAG_DIRECT_BOOT_AUTO = 256;
public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16;
public static final int FLAG_FROM_BACKGROUND = 4;
public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 64;
public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 128;
public static final int FLAG_GRANT_READ_URI_PERMISSION = 1;
public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2;
public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32;
public static final int FLAG_RECEIVER_FOREGROUND = 268435456;
public static final int FLAG_RECEIVER_NO_ABORT = 134217728;
public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824;
public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912;
public static final int FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS = 2097152;
内容较多,就不一一介绍。有兴趣可自行查阅~
IntentFilter
IntentFilter又叫意图过滤器,可以说是将应用域名话的一种方式,通过配置IntentFilter可以帮助我们如同访问网址一般的迅速定位到属于我们的应用,使用类似与浏览器的url的形式,Android中也有着它的唯一标识URI。也可以通过配置意图来添加唤醒我们的方式、给我们添加标识。