应用程序返回前台时出现问题

发布于 2024-11-27 14:29:01 字数 1539 浏览 0 评论 0原文

我的应用程序在与其他应用程序一起使用一段时间后返回前台时崩溃,并且我不知道如何修复它。

我的应用程序有一个启动屏幕活动,它从 Web 服务加载一些数据并将其放入扩展应用程序的类中声明的全局静态变量中,如 这个问题。加载所有数据后,此活动将启动一个主页活动,其中包含一些可在应用程序中导航的菜单。全局变量用于大多数活动。

在某些时候,在使用其他应用程序时,我的应用程序似乎被杀死了,因为我可以在 logcat 中看到这一点:

I/ActivityManager( 2465): Process com.mysite.myapp (pid 23538) has died.
I/WindowManager( 2465): WIN DEATH: Window{4852a678 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{485b63a8 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{4826fbf8 com.mysite.myapp/com.mysite.myapp.ItemList paused=false}
I/WindowManager( 2465): WIN DEATH: Window{48286f90 com.mysite.myapp/com.mysite.myapp.ItemDetail paused=false}
W/GpsLocationProvider( 2465): Unneeded remove listener for uid 1000
D/GpsLocationProvider( 2465): stopNavigating
D/gps_BRCM( 2465): [status check] on_stop() : GPS_STATUS_SESSION_END
D/gps_BRCM( 2465): gps_engine_status_update 2
D/GpsLocationProvider( 2465): send an intent to notify that the GPS has been enabled or disabled
D/gps_BRCM( 2465): gps_stop: called
V/GpsLocationProvider( 2465): hybridGpsSensorDeregister : No registered sensorManager
D/GpsLocationProvider( 2465): hybridGpsSensorDeregister

并且调试器已分离。

现在,当我再次打开我的应用程序时,如果最新的活动不使用全局变量(在这种情况下,当我导航到使用全局变量的活动时,它就会崩溃),或者如果使用了,则立即崩溃。

如果我的应用程序被终止(这似乎是这种情况,因为即使我的位置服务也停止了,如 logcat 中所示),为什么它会打开最新的活动而不是从启动屏幕再次启动?

my app crashes when it comes back to foreground after some time playing with others applications and I can't find out how to fix it.

My app has a splash screen activity where it loads some data from web services and put it in global static variables declared in a class extending Application, as explained in this SO question. Once all data are loaded, this activity launches a Home activity with some menu to navigate in the app. The global vars are used in most activities.

At some point, while playing with other apps, it seems that my app is killed, because I can see this in the logcat:

I/ActivityManager( 2465): Process com.mysite.myapp (pid 23538) has died.
I/WindowManager( 2465): WIN DEATH: Window{4852a678 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{485b63a8 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{4826fbf8 com.mysite.myapp/com.mysite.myapp.ItemList paused=false}
I/WindowManager( 2465): WIN DEATH: Window{48286f90 com.mysite.myapp/com.mysite.myapp.ItemDetail paused=false}
W/GpsLocationProvider( 2465): Unneeded remove listener for uid 1000
D/GpsLocationProvider( 2465): stopNavigating
D/gps_BRCM( 2465): [status check] on_stop() : GPS_STATUS_SESSION_END
D/gps_BRCM( 2465): gps_engine_status_update 2
D/GpsLocationProvider( 2465): send an intent to notify that the GPS has been enabled or disabled
D/gps_BRCM( 2465): gps_stop: called
V/GpsLocationProvider( 2465): hybridGpsSensorDeregister : No registered sensorManager
D/GpsLocationProvider( 2465): hybridGpsSensorDeregister

and the debugger is detached.

Now, when I open my app again, the latest activity is started if it does not use global vars (in that case it crashes as soon as I navigate to an activity which does), or crashes immediately if it does.

If my app was killed, which seems to be the case because even my location service is stopped, as seen in the logcat, why does it open the latest activity instead of launching again from the splash screen?

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

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

发布评论

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

评论(3

夜司空 2024-12-04 14:29:02

当 Android 杀死你的应用程序时,它这样做只是为了节省资源。为了获得更好的可用性,操作系统将记住您在该应用程序中的位置(如果您实现了正确的侦听器,则保存诸如活动堆栈和实例状态之类的内容)。

当您恢复应用程序时,它将恢复活动和其他所有内容。当您将数据保存到全局静态变量时,这些数据可能在应用程序终止时“丢失”!

我建议您使用数据库或至少在使用之前检查数据是否仍然存在(例如:MyClassHolder.myGlobalStaticParameter == null

When android kills your application, it is doing so only to save resources. In order to have a better usability, the OS will remember where you were inside that app (saving things like the activity stack a instance state if you implement the proper listeners).

When you restore your app, it will restore the activities and everything else. As you were saving data to global static variables, these might have been "lost" when the application was terminated!

I suggest you to use databases or at least check if the data is still there before using it (for example: MyClassHolder.myGlobalStaticParameter == null)

九命猫 2024-12-04 14:29:01

这不是对您问题的直接回答,但我认为它可能有用。

您将数据存储在全局变量中的决定是错误的。这是因为每次用户离开应用程序时,您的应用程序都可能被终止。当他或她回来时,您将需要重新加载数据。

您应该使用 ContentProviderServiceService 应从互联网加载数据并将其存储到 ContentProviderContentProvider 应保留数据。所有活动都应使用 ContentProvider 来访问此缓存数据。

这样您的应用程序:

  1. 不需要每次启动应用程序时下载数据(节省 CPU、电池和带宽)
  2. 您的活动可以依赖于 ContentProvider 中缓存的数据这一事实。
  3. 每次ContentProvider中的数据更新时,每个Activity都可以收到通知并更新UI。
  4. ContentProvider 中的数据在应用程序运行期间保留(例如,如果您使用 SQLite)。
  5. 从 Web 服务读取数据并将其与 ContentProvider 同步的后台服务与 Activity 完全解耦。

当然,您需要投入一些时间来实现 ServiceContentProvider,以及在 Acitivity 中进行正确处理。但您的应用程序将更加健壮和可扩展(您可以轻松添加新组件)。

This is not direct answer to you question, but I thought it might be useful.

Your decision to store data in global variables is bad. That's because your app can be killed each time user navigates away from it. And when he or she comes back you'll need to load data all over again.

You should use ContentProvider and Service. Service should load data from internet and store it to ContentProvider. ContentProvider should persist data. All activities should use ContentProvider to access this cached data.

This way your application:

  1. Will not need to download data every time application is started (saving CPU, battery and bandwidth)
  2. Your activities can rely on the fact that there is cached data in ContentProvider.
  3. Every time data is update in ContentProvider, each Activity can be notified and update UI.
  4. Data in ContentProvider is persisted across application runs (if you use SQLite for example).
  5. Background service that reads data from web-service and syncs it with ContentProvider is completely decoupled from Activities.

Of cause you need to invest some time into implementing Service and ContentProvider, and proper handling in Acitivities. But your application will be more robust and scalable (you can easily add new components).

ゃ人海孤独症 2024-12-04 14:29:01

解决您的问题的一个肮脏的解决方法是检查全局变量是否已填充 onResume 方法。如果变量未填充,则使用 CLEAR_TOP< 的 Intent 启动闪屏活动/a> 标志已设置。这应该会导致您的所有活动从活动堆栈中删除,并且您的启动屏幕将加载并能够重新加载应用程序运行所需的所有数据。

这是一个肮脏的解决方法,可以帮助设计糟糕的应用程序工作。
如果您希望您的应用程序对您和用户都更好,请使用 inazaruk 提供的解决方案。他关于应用程序的基本设置是正确的。

A dirty workaround to your problem is to check if the global variables are filled in the onResume method of your activities. If the variables are not filled start the splashscreen activity with an Intent with the CLEAR_TOP flag set. This should cause all your activities to be removed from the activity stack and your splash screen will load and is able to reload all the data needed for your app to work.

This is a dirty workaround to help a badly designed application to work.
If you want your app to be nicer to you and the user go with the solution inazaruk provided. He is correct about the basic setup of an application.

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