Android 应用程序类生命周期

Posted

技术标签:

【中文标题】Android 应用程序类生命周期【英文标题】:Android Application Class Lifecycle 【发布时间】:2011-06-02 21:45:06 【问题描述】:

我正在开发的 android 应用程序会覆盖 Application 类以将轻量级状态(用户名、gps 位置等)存储在静态变量中。此状态的大部分设置在启动活动的 OnCreate 中(从首选项检索用户名,位置侦听器运行)。依赖启动活动来初始化 Application 类是否安全?是否有任何情况下可能会重新创建 Application 类而不创建 Launch 活动?

问题出现是因为我在手机睡了几个小时后恢复应用程序时遇到了一个空指针异常,它访问了应用程序类中的一个变量(应用程序在手机进入睡眠状态之前留在前台)。是否有可能在手机睡着和唤醒手机时终止进程,重新创建 Application 类,恢复堆栈中的顶部活动,但启动 activity.onCreate 没有运行,因此 Application 类没有初始化?

请注意,我已尝试通过强制应用停止使用“设置”/“管理”应用来测试这些场景。但是,我无法重现该问题。下次运行时,会创建 Application 类,然后是启动 activity.onCreate。

是否可以安全地假设 Application 类实例将与进程一样存在,并且在创建 Application 类时它相当于“重新启动”应用程序,即。从一个新的活动堆栈开始(堆栈上的第一个活动是启动活动)?

【问题讨论】:

不确定是否有帮助,但你读过这个吗:developer.android.com/guide/topics/fundamentals.html#actlife 您是如何解决问题的? 【参考方案1】:

“我在恢复应用程序时遇到了访问 Application 类中的变量的空指针异常”

检查此链接.. http://www.developerphil.com/dont-store-data-in-the-application-object/

【讨论】:

【参考方案2】:

简而言之:在YourApplication.onCreate 中进行初始化,而不是一些 LaunchActivity

要检查的文件: - Processes and Threads - API Guides > Activities

依赖启动活动来初始化应用程序类是否安全?

是的,只要您记住 Application 可以存在的时间比 Activity 更长,并且 Activity 可能会被杀死并重新创建。我不确定 Intent 会复活 Activity 得到什么:LAUNCH 或 VIEW (对于活动因过于繁重而被杀死的情况,而应用程序绑定了长时间运行的服务)

在没有创建 Launch 活动的情况下,是否可以重新创建 Application 类?

是的,如果最后一个可见活动不是 LaunchActivity 检查Android application lifecycle and using of static

是否有可能进程在手机睡着时被杀死,在唤醒手机时,应用程序类被重新创建,堆栈中的顶部活动被恢复,但启动 activity.onCreate 没有因此运行Application 类没有初始化?

如果有几个不同的Activity启动了A,B,C并且它们整个进程被杀死了,那么我认为Android OS只创建Application和C Activity是好的,而A和B会在访问时重新创建,即回到他们身边。

假设Application类实例只要进程存在就安全吗,

是的

并且当 Application 类被创建时,它相当于“重新启动”应用程序,即。从一个新的活动堆栈开始(堆栈上的第一个活动是启动活动)?

我不确定何时会首先调用启动活动, 但最后一个,即用户应该看到的那个。

【讨论】:

【参考方案3】:

您可以通过正在运行的应用程序的killing the process 来测试场景。

第 1 步。打开您的应用,然后按Home 按钮将其隐藏到背景中。

第 2 步。调用 adb shell

Step 3. 输入命令su(你必须获得ROOT权限才能杀死进程)

第 4 步。ps(列出所有正在运行的进程 ID 并找到您的)

第 5 步。kill 1234(假设您的应用程序在进程 1234 上运行)

第 6 步。然后,返回您的设备并再次单击启动图标。您可能会发现活动堆栈上的最后一个活动重新打开。您可能还会发现该活动调用了onRestoreInstanceState() 方法。

【讨论】:

【参考方案4】:

没有。您的整个应用程序可以在任务堆栈完好无损的情况下被终止并重新创建;这使系统可以在需要它的设备上回收内存,同时仍向最终用户呈现多任务处理的无缝错觉。来自文档:

后台活动(活动 对用户不可见,并且 已暂停)不再 关键,因此系统可以安全地 杀死它的进程以回收内存 其他前台或可见进程。 如果它的进程需要被杀死, 当用户导航回 活动(使其在 再次屏幕),它的 onCreate(Bundle) 方法将被调用 之前的 savedInstanceState 提供在 onSaveInstanceState(Bundle) 以便它 可以在相同的状态下重新启动 就像用户上次离开它一样。

也就是说,进程(与应用程序相关联)可以被终止但随后重新启动,并且各个活动应该有足够的信息来根据他们在被终止之前保存的内容重新创建自己,而不依赖于全局状态由其他活动在流程中设置。

考虑将需要由 Activity 初始化的持久共享状态存储在 SharedPreference 或 SQLite 数据库中,或者将其作为 Intent extra 传递给需要它的 Activity。

【讨论】:

呃。关于如何测试这种情况的任何建议?正如我所提到的,当我手动终止 proc 时,活动堆栈不会保持完整。 这似乎对我不起作用。我在 2 台设备(1.6 和 2.3)上进行了尝试 - 我使用硬主页键将应用程序置于后台,然后从“管理应用程序”中“手动停止”,单击主屏幕上的我的应用程序图标。该应用程序仍会随着启动活动重新启动。而且它不仅仅是清除顶部活动 - 当我将它放在后台时,堆栈是几个活动。当然,没有设置 android:cleartaskonlaunch ... 我非常感谢这次问答,因为我发现我的应用程序的全局状态(保存在 .Application 类中)经常被杀死,即使 Activity 堆栈明显仍然存在完好无损的。为了解决这个问题,我的所有活动必须能够优雅地应对下次它们进入前台时不再存在的全局状态,并在这种情况下触发全局状态的重建。 我有一个有趣的额外观察是,当我的应用程序在后台时,它的.Application(可能是进程)似乎被循环杀死然后重新实例化,具体取决于手机的其他内容是在做。因此,如果手机正在播放音乐,如果我有一个Toast 来指示.Application 实例化,我会经常看到Toast。这发生在我的 HTC One X 上,我认为它是用于这种行为的非常好的边缘案例测试设备,因为 One X 以内存不足而闻名,甚至有时会杀死启动器以释放 RAM! 此外,我只能假设我的应用程序.Application 的循环终止和重新实例化是系统试图通过再次准备好之前由于低而必须终止的任何进程来改善用户体验内存。这让我意识到,在 .Application 实例化时开始任何冗长的重建全局状态的工作是一个坏主意。

以上是关于Android 应用程序类生命周期的主要内容,如果未能解决你的问题,请参考以下文章

Android学习笔记 Activity的生命周期

android之Activity的生命周期

activity生命周期

Android LiveData使用

Android Jetpack之LiveData源码分析

(Android第一行代码活动的生命周期)生命周期