4

因为我正在构建的应用程序将处理相当敏感的数据,所以我想在每次用户登录时将 SQLite 数据库与服务器同步,并在每次应用程序失去焦点时删除数据库(因为用户移动到主屏幕或另一个应用程序)。

看到Activity 生命周期,我的想法是通过在每个 Activity 的 onDestroy 中清空数据库来做到这一点。为了测试所描述的生命周期,我只需覆盖所有生命周期方法(onCreate、onStart、onResume、onPause、onStop 和 onDestroy),在其中包含一些日志消息,然后启动我的应用程序。

日志消息包含在我的 SettingsActivity 中。当我进入我的应用程序并移动到设置时,它会运行 onCreate、onStart 和 onResume(如预期的那样)。然后,当我单击一个设置并移至下一个屏幕时,它会运行 onPause 和 onStop(仍如预期的那样)。要返回设置屏幕,我单击后退按钮,它会再次运行 onStart 和 onResume(仍然如预期的那样),当我现在再次单击后退按钮返回初始屏幕时,它(令我惊讶的是)运行 onPause, onStop 和 onDestroy。

所以我的问题;

  1. 为什么在应用程序未完成时会销毁 Activity?
  2. 更重要的是:当应用程序关闭或失去焦点时,我如何运行我的 CleanUp 方法?
4

4 回答 4

10

您可以在这里获得更多信息:http: //developer.android.com/training/basics/activity-lifecycle/stopping.html

即使我认为您已经阅读了它,因为您已经研究了活动生命周期,您也可以在第一张图中看到,在onDestroy()之后调用了onStop()并且此调用完全由系统管理:您不应该期望任何行为。系统将自行决定何时调用此方法,有时,此方法永远不会被调用(参见此处:http: //developer.android.com/reference/android/app/Activity.html)。当系统需要内存时,您的活动将通过onStop(),仅此而已。

因此,要回答您的第二个问题,您应该阅读文档中有关该onDestroy()方法的注释:

注意:不要指望这个方法被称为保存数据的地方!例如,如果一个活动正在内容提供者中编辑数据,那么这些编辑应该在 onPause() 或 onSaveInstanceState(Bundle) 中提交,而不是在这里。此方法通常用于释放资源,例如与活动相关联的线程,以便被破坏的活动不会在其应用程序的其余部分仍在运行时留下这些东西。在某些情况下,系统会简单地终止 Activity 的宿主进程,而不会在其中调用此方法(或任何其他方法),因此不应使用它来执行打算在进程消失后保留的事情。

所以很明显,这是一个进行清理过程的坏地方。所以你应该使用其中一种onPause()onStop()方法。

onStop()在文档中是这样描述的:

当您不再对用户可见时调用。接下来,您将收到onRestart()onDestroy()或什么都没有,这取决于以后的用户活动。

onPause()在文档中是这样描述的:

当活动进入后台但尚未(尚未)被杀死时,作为活动生命周期的一部分调用。[...] 当活动 B 在活动 A 之前启动时,将在 A 上调用此回调。在 A 的 onPause() 返回之前不会创建 B,因此请确保不要在这里做任何冗长的事情。 [...] 在系统需要更多内存的情况下,它可能会终止暂停的进程以回收资源。

我们现在知道,onPause()它旨在让您保存数据,并且在onPause()执行后,系统可能会终止您的进程。因此,进行清理onPause()似乎是最安全的地方,因为您很确定每次都会调用它。

此外,正如您所读到的,在此处进行清理可能会使您的应用程序变慢,但无论如何,在每次获得/失去焦点时清理和重新创建数据库都是一个非常繁重的过程......

恢复:让你的清理进程在onPause()方法和你的init进程中onResume()请记住,您的应用程序在这种过程中可能会非常慢。

希望这可以帮到你。

于 2013-10-24T08:31:23.720 回答
2

销毁背面的 Activity 是正常行为。来自Android 开发者网站

在某些情况下,由于正常的应用行为,您的 Activity 会被破坏,例如当用户按下后退按钮时......

用于检测应用程序何时进入后台,没有简单的方法调用可以让您知道这一点。然而,这个先前的问题包含一些关于如何做到这一点的好答案。

于 2013-10-24T08:10:37.590 回答
0

您不能在应用程序的 java 部分执行此操作(调用函数)。仅在原生部分。

于 2013-10-24T08:00:17.323 回答
0

关于您的第二个问题,这样您可以在应用程序完全关闭时运行您的 CleanUp 方法。您需要在服务中实现您的方法,在这种情况下,我将其命名为“ExitService”

首先创建这个服务类:

 public class ExitService extends Service {


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        System.out.println("onTaskRemoved called");
        super.onTaskRemoved(rootIntent);
        //do something you want before app closes.

ADD YOUR METHOD HERE, or CALL IT

        //stop service
        this.stopSelf();
    }
}

然后,以这种方式在清单“应用程序”标签中声明您的服务:

<service
            android:enabled="true"
            android:name=".ExitService"
            android:exported="false"
            android:stopWithTask="false" />

现在,只需在您的应用关闭之前,在任何您想做某事的地方启动服务。

 Intent intent = new Intent(this, ExitService.class);
        startService(intent);
于 2018-03-19T20:18:39.353 回答