Android应用程序类生命周期

发布于 2024-10-10 06:58:53 字数 599 浏览 5 评论 0原文

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

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

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

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

The android app I am working on overrides the Application class to store lightweight state (username, gps location, etc) in static vars. Most of this state is set in OnCreate of the launch activity (username retrieved from prefs, location listener runs). Is it safe to rely on the launch activity to initialize the Application class? Are there any cases where the Application class might be re-created without the Launch activity also being created?

The question comes up because I ran into a null pointer exception accessing a variable in the Application class on resuming the app after the phone was asleep for several hours (the app was left in the foreground before phone went to sleep). Is it possible that the process was killed while the phone was asleep and on waking the phone, the Application class was re-created, the top activity in the stack was resumed, but the launch activity.onCreate wasn't run thus the Application class wasn't initialized?

Note that I have tried to test these kinds of scenarios by Forcing the App to stop using Settings / Manage applications. However, I'm not able to recreate the problem. On the next run, the Application class is created, followed by the launch activity.onCreate.

Is it safe to assume that the Application class instance will exist as long as the process, and that when the Application class is created it is equivalent to "restarting" the application ie. start with a new activity stack (and first activity on stack is the launch activity)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

焚却相思 2024-10-17 06:58:53

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

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

也就是说,进程(应用程序所绑定的进程)可以被杀死,然后重新启动,并且各个活动应该有足够的信息来从被杀死之前保存的内容中重新创建自己,而不依赖于在进程中设置的全局状态。由其他活动处理。

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

No. Your entire application can be killed and recreated with the task stack intact; this lets the system reclaim memory on devices that need it while still presenting a seamless illusion of multitasking to the end user. From the docs:

A background activity (an activity
that is not visible to the user and
has been paused) is no longer
critical, so the system may safely
kill its process to reclaim memory for
other foreground or visible processes.
If its process needs to be killed,
when the user navigates back to the
activity (making it visible on the
screen again), its onCreate(Bundle)
method will be called with the
savedInstanceState it had previously
supplied in
onSaveInstanceState(Bundle) so that it
can restart itself in the same state
as the user last left it.

That is, the process (which the Application is tied to) can be killed off but then restarted, and the individual activities should have enough info to recreate themselves from what they've saved before being killed, without relying on global state set in the process by other Activities.

Consider storing persistent shared state that needs initialization by an Activity in either a SharedPreference or SQLite database, or passing it to Activities that need it as an Intent extra.

暖树树初阳… 2024-10-17 06:58:53

您可以通过终止正在运行的应用程序的进程来测试该场景。

步骤 1. 打开您的应用程序,然后按 Home 按钮将其隐藏到后台。

步骤 2. 调用 adb shell

步骤 3. 输入命令 su (您必须获得 ROOT 权限才能终止进程)

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

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

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

You can test the scenario by killing the process of your running application.

Step 1. Open your app, and then press Home button to hide it into background.

Step 2. Invoke adb shell

Step 3. Enter command su (you have to get ROOT permission in order to kill process)

Step 4. ps (list all running process ID and find yours)

Step 5. kill 1234 (assume your application running on process 1234)

Step 6. Then, go back to your device and click the launch icon again. You may find the last activity on activity stack is reopen. You may also find onRestoreInstanceState() method is called for the activity.

半岛未凉 2024-10-17 06:58:53

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

检查一些 LaunchActivity 文档:
- 进程和线程
- API 指南 >活动

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

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

是否存在可能重新创建应用程序类而未创建启动活动的情况?

是的,如果最后一个可见活动不是 LaunchActivity
检查Android应用程序生命周期和静态的使用

是否有可能在手机处于睡眠状态时进程被终止,并且在唤醒手机时,重新创建了 Application 类,恢复了堆栈中的顶部 Activity,但启动 Activity.onCreate 并未运行,因此Application 类未初始化?

如果有几个不同的活动启动了 A、B、C 并且它们的整个进程被杀死,那么我认为 Android 操作系统很好,只创建应用程序和 C 活动,而 A 和 B 将在访问时重新构建,即返回到他们。

是否可以安全地假设应用程序类实例将与进程一样存在,

是的

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

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

In short: do initilization in YourApplication.onCreate, not some LaunchActivity

Docs to check:
- Processes and Threads
- API Guides > Activities

Is it safe to rely on the launch activity to initialize the Application class?

Yes, as long as you remember that Application can exist longer that Activity and the Activity may be killed and recreated. I am not sure what Intent will resurrected Activity get: LAUNCH or VIEW
(For scenario when activity was killed as too heavy, while there was long running service binded to app )

Are there any cases where the Application class might be re-created without the Launch activity also being created?

yes, if the last visible activity was not LaunchActivity
check Android application lifecycle and using of static

Is it possible that the process was killed while the phone was asleep and on waking the phone, the Application class was re-created, the top activity in the stack was resumed, but the launch activity.onCreate wasn't run thus the Application class wasn't initialized?

If there were several different Activities launched A, B, C and them whole process killed, then I think Android OS is good with only creating Application and C activity, while A and B would be re-creted on access, that is on returning to them.

Is it safe to assume that the Application class instance will exist as long as the process,

yes

and that when the Application class is created it is equivalent to "restarting" the application ie. start with a new activity stack (and first activity on stack is the launch activity)?

I not sure when restarting the launch activity would be called first,
but the last, i.e. the one that user should see.

情徒 2024-10-17 06:58:53

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

检查此链接。
http://www.developerphil.com/dont-store -应用程序对象中的数据/

"I ran into a null pointer exception accessing a variable in the Application class on resuming the app"

Check this link..
http://www.developerphil.com/dont-store-data-in-the-application-object/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文