调用 finishAffinity() 不会破坏 android 应用或活动。即使重新启动应用,活动数据仍会保留

2022-09-03 00:43:32

这是一个巨大的Android编程问题/错误。

调用 finishAffinity() 不会关闭我的应用程序。
这可以从以下事实中得到证明:

1.Android Studio调试器仍然说“应用程序正在运行”,即使应用程序从屏幕上消失并且我又回到了手机主屏幕。

2. “重新启动”应用程序时,初始活动的数据成员的值与应用程序“关闭”之前的值保持不变。

3. 如果我在 finishAffinity() 之后直接调用 System.exit(0),则关闭工作正常,数据成员被重置为其初始默认值。


这个问题还有更大的影响!当我在启动另一个 ActivityB 后在 ActivityA 中调用 finish() 时,如果我返回到 ActivityA,则数据成员尚未重置为默认值仍然是旧值。

这对我来说是令人困惑的,因为我来自C++当一个类被摧毁时,它实际上被摧毁了,所有与它相关的内存都被完全释放了。

让活动在切换到新活动或尝试退出应用程序时完全删除自身似乎是不可能的。

public class Startup extends AppCompatActivity
{
    private static int iStarted = 0;

    ............

    @Override
    protected void onActivityResult(int request, int result, Intent data)
    {
        super.onActivityResult(request, result, data);

        if (request == RESULT_EULA_RETURNED)
        {
            // shutdown
            finishAffinity(); // iStarted remains = 1
            return;
        }
    }

    ..........

    @Override
    protected void onResume()
    {
        super.onResume();

        // perform startup
        // even when restarted this remains  = 1
        if (iStarted == 0)
        {
            iStarted = 1; // this will stay = 1 until the application is manually killed via the CLOSE ALL method or via the debugger
        }
    }
}

答案 1

finishAffinity()不用于“关闭应用程序”。它用于从当前任务(可能包含属于多个应用程序的 s)中删除属于特定应用程序的许多 s。ActivityActivity

即使您完成了应用程序中的所有操作,托管应用的操作系统进程也不会自动消失(就像调用 时一样)。Android最终会在进程接近它时杀死它。你无法控制这一点(这是故意的)。ActivitySystem.exit()

如果将调试器附加到进程,这还可以防止进程被 Android 杀死,因为调试器会在进程中保留活动对象。

你谈到“数据成员”没有被清理,你声称这在C++中的工作方式不同。实际上,事实并非如此。您的“数据成员”已声明。它们不是实例变量,而是类变量。它们只存在一次(不是在类的每个实例中),它们在加载类时创建和初始化,并且在卸载类之前永远不会被销毁(这在Android上永远不会发生)。C++具有完全相同的行为。static

您可以尝试使用实例变量而不是类变量来解决您的问题。


答案 2

Android没有“关闭我的应用程序”的概念。只有安卓的生命周期。在活动生命周期上,VM 的对象生命周期之间没有连接;Android 可以自由地在创建/销毁边界时重复使用您的对象实例。简而言之,你不能假设Android会构造一个新对象来处理生命周期事件。ActivityActivityActivity

您需要管理自己的状态。例如,您可能希望清除它们,以便每当重新创建活动时,它们都会重置。请注意,我不想知道你想用什么逻辑来解决这个问题,我只是举个例子。onCreate()


推荐