一、概念
1.1 生命周期
| onCreate() |
在创建应用程序时调用。可以重写这个方法来实现实例化应用程序单态,以及创建和实例化任何程序状态变量和共享资源。
|
| onTerminate() | 终止应用程序时调用,不能保证一定会被调用。 |
| onLowMemory() |
当系统处于资源匮乏的时候,具有良好行为的应用程序可以释放额外的内存。这
个方法一般只会在后台进程已经终止,但是前台应用程序仍然缺少内存时调用。可以重写这个处理程序来清空缓存或释放不必要的资源。
|
| onTrimMemory() |
作为onLowMemory的一个特定于应用程序的替代选择,在Android4.0时引
入。当运行时决定当前应用程序应该尝试减少其内存开销时调用,它包含一个level参数,用于提供请求 的上下文。
|
|
onConfigurationChanged()
|
与Activity不同,在配置改变时,应用程序对象不会被终止和重启。
如果应用程序使用的值依赖于特定的配置,则重写这个方法来重新加载这些值,或在应用程序级别处理
配置改变。
|

二、使用
2.1 全局监听 Activity 生命周期
监听整个应用进程中所有 Activity 的生命周期变化。无论 Activity 是自己写的还是 sdk 的,只要它运行在你的进程里,它的生命周期回调都会被这个监听器捕获。解耦了 BaseActivity,提供上帝视角的生命周期感知,实现热启动监听、全局栈管理的最佳方案。
可以注册多个 ActivityLifecycleCallbacks 实例。在 Application 内部,它维护了一个 ArrayList<ActivityLifecycleCallbacks>,注册时只是把监听器添加到列表里。当生命周期事件触发时,Application 会遍历列表依次调用所有注册的监听器。因此不要把所有逻辑(栈管理、打点、业务检查)都塞进同一个监听器中,后期会难以维护。
- 多进程问题:Application.onCreate 会在每个进程创建时执行。如果App 有多个进程(比如推送进程、小程序进程),务必判断 if (isMainProcess),否则监听逻辑会在每个进程里都跑一遍,导致重复上报或逻辑错误。
- 初始化顺序:一定要在 Application.onCreate() 中靠前注册,如果注册晚了(比如在 SplashActivity 之后),可能会漏掉第一个页面的 onCreate 回调。
val activityLifecycleCallbacks = object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivityDestroyed(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
}
override fun onCreate() {
registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
}
unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks)
2.1.1 判断 APP 前后台切换
通过计算“处于 Started 状态的 Activity 数量”,可以判断 APP 是进入了前台还是切到了后台。onActivityStarted: 计数器 +1, onActivityStopped: 计数器 -1, 如果计数从 0 变 1 App 进入前台(冷启动/热启动),如果计数从 1 变 0 App 进入后台。这种方式比监听 ON_START 事件更底层,不依赖 Jetpack 库,且兼容性极好。
private var activityCount = 0
private val callback = object : ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
activityCount++
if (activityCount == 1) {
// APP回到前台:检查更新、同步配置、上报活跃日志
}
}
override fun onActivityStopped(activity: Activity) {
activityCount--
if (activityCount == 0) {
// APP 进入后台
}
}
}
2.1.2 Activity栈管理(一键退出)
有时候需要“退出登录”,要求关闭所有页面并回到登录页。如果手动 finish() 很容易漏掉某个中间页。可以用一个 List 维护所有活着的 Activity。
当屏幕旋转时 Activity 会销毁重建,onActivityDestroyed -> onActivityCreated,如果 StackManager 逻辑不够健壮,可能会导致引用了已经销毁的 Activity。
private val activityStack = Stack<Activity>()
private val callback = object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
activityStack.push(activity)
}
override fun onActivityDestroyed(activity: Activity) {
activityStack.remove(activity)
}
}
fun finishAllActivity() {
for (activity in activityStack) {
if (!activity.isFinishing) {
activity.finish()
}
}
activityStack.clear()
}
2.2 多进程下Application多次创建问题
通常会将一些初始化代码放在 Application 中,而每当运行指定了进程的组件时都会新建一个 Application 对象,由于不是同一个所以数据不通用,只需要在 Application 类中对当前进程加以判断即可。
override fun onCreate() {
super.onCreate()
if (isMainProcess()) init() //确保在主进程下才初始化(多进程会导致Application重复创建)
}
/**
* 当前进程是否为主进程
*/
private fun isMainProcess(): Boolean {
val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
val runningProcesses = activityManager.runningAppProcesses
if (runningProcesses != null) {
for (process in runningProcesses) {
if (packageName.equals(process.processName)) {
return true
}
}
}
return false
}
2.3 无埋点页面统计
要统计每个页面的访问次数和停留时长,如果让每个 Activity 自己去上报,代码会非常冗余。利用 LifecycleCallbacks,可以在一个地方搞定全应用统计。
private val callback = object : ActivityLifecycleCallbacks {
override fun onActivityResumed(activity: Activity) {
// 开始计时
PageTracker.startRecord(activity.javaClass.simpleName)
}
override fun onActivityPaused(activity: Activity) {
// 结束计时并上报
PageTracker.stopRecordAndReport(activity.javaClass.simpleName)
}
}
三、其它
3.1 getApplication() 和 getApplicationContext() 区别?
获得的对象相同,作用域不同(语义的区别,getApplication() 只在 Activity 和 Service 中有,在别的地方获取例如 BroadcastReceiver 中就要使用 getApplicationContext() 了)。getBaseContext() 获取的是 ContextImpl。
本文介绍了Android应用中关键生命周期方法如onCreate、onTerminate、onLowMemory等的使用场景,强调了在多进程中处理Application重复创建的问题,并提到了onTrimMemory和onConfigurationChanged的用途。

8万+

被折叠的 条评论
为什么被折叠?



