【问题标题】:Issue with global variables全局变量问题
【发布时间】:2025-01-01 20:00:02
【问题描述】:

我通过扩展Application在我的应用中定义了一些全局变量,如下图。当我离开应用程序时,打开更多应用程序并与它们一起玩一会儿,然后回到我的应用程序,全局变量已被删除,我的应用程序崩溃了。我有两个问题:

1- 这怎么可能?

2- 进入后台时如何强制我的应用退出?我知道我不应该这样做,但我找不到其他解决方案...

谢谢

public class GlobalVars extends Application { 

    public static HashMap<Integer, String> ID2Cat = new HashMap<Integer, String>();

    // User logged bool
    public static boolean isLogged = false;

    // Current menu item
    public static int currentMenuItem = 0;
    public static boolean isHome = false;

    // Goodideas    
    public static JSONObject goodIdeas = new JSONObject();

    // Meteo
    public static JSONArray weatherItems = new JSONArray();

    // More stuff

}

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

【问题讨论】:

    标签: android global-variables


    【解决方案1】:

    1- 这怎么可能?

    您的进程可能随时终止。您不能假设任何静态数据成员或自定义 Application 对象将存在多长时间。它们最多只能用作缓存。

    2- 进入后台时如何强制我的应用退出?

    你没有。

    我知道我不应该这样做

    不仅如此,在这种情况下它也对您没有帮助。它所要做的只是意味着你 100% 的时间会崩溃,因为你实际上并没有费心去正确初始化。

    但我找不到其他解决方案。

    初始化您的数据。如果您的应用程序由于创建了新的自定义 Application 实例而崩溃,则您的 Application 子类存在错误,您需要修复这些错误。

    【讨论】:

    • “初始化数据”是什么意思。启动应用程序时,会显示一个初始屏幕,在此期间初始化所有全局变量。没有办法让只有在应用被终止时(即所有活动都完成时)才删除的数据?
    • @jul:“启动应用程序时,会显示一个初始屏幕,在此期间所有全局变量都被初始化。” ——这不是明智之举。 “没有办法只有在应用程序被终止时(即所有活动都完成时)才删除数据?” - 这就是已经发生的事情。但是,当操作系统决定时,“所有活动都已完成”,这可以是任何时候。如果用户离开您的应用,Android 可以随时完成活动并终止流程。
    • 为什么在启动画面中加载我的所有数据(即应用程序启动时)不是明智之举?我从 Web 服务中获取它们,然后执行 http 请求 + 解析 json 会使应用程序的响应速度降低。此外,当我在后台打开我的应用程序时(例如使用另一个应用程序),它应该重新启动并加载我的初始化数据,或者如果活动没有被终止,则从我离开它的地方开始。在前一种情况下,如果活动还活着,我的全局变量不应该被删除,对吧?
    • @jul:“为什么在启动画面中加载我的所有数据(即应用程序启动时)不是明智之举?” -- 因为用户想使用你的应用程序,而不是盯着启动画面。在后台加载数据时,重新设计您的应用程序以提供一些 真正的 功能。在此过程中,即使您的进程已终止,您也可以安排触发此数据加载。 “它应该重新开始并加载我的初始化数据,或者如果活动没有被杀死,则从我离开它的地方开始” - 你的证明是......究竟是什么?
    • 我添加了让我认为我的应用程序被杀死的 logcat。这就是为什么我不明白为什么它不从头开始(即从加载数据的启动画面)。
    【解决方案2】:

    您应该使用适当的生命周期事件处理程序来保存数据并在重新激活时恢复数据:onSaveInstanceState()、onPause() 和 onResume()。您不能安全地假设您的全局字段将保持不变。

    我建议您熟悉一下Activity life-cycle

    【讨论】:

      【解决方案3】:

      很简单,你必须在Application.OnCreate中初始化你声明的变量,我刚刚测试过它可以工作,当应用程序崩溃时它会再次调用Application.OnCreate。

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        @Override onPause 在你的活动中然后使用finish();

        【讨论】:

          【解决方案5】:

          Application 类用于初始化全局变量 - 所以这部分是正确的。但是,您必须在另一个类中声明这些变量,因为 Application 仅在应用程序重新启动时调用 - 而不是在后台时调用。

          您还应该在ApplicationonCreate() 方法中进行这些初始化(使用@Override 注释)。

          【讨论】:

            【解决方案6】:

            我遇到了类似的问题,基本上这篇文章解释得很好http://www.developerphil.com/dont-store-data-in-the-application-object/

            这是关键段落以及发生在你身上的事情:

            这给我们带来了问题的核心:应用程序对象不会永远留在内存中,它会被杀死。与流行的看法相反,该应用程序不会从头开始重新启动。 Android 将创建一个新的 Application 对象并在用户之前所在的位置启动 Activity,从而给人一种应用程序从一开始就没有被杀死的错觉。

            我知道这篇文章很旧,但认为这可能对未来的用户有所帮助。

            【讨论】: