如何在Android应用关闭或失去焦点时调用方法?

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

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

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

所以我的问题;

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

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

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

因此,要回答第二个问题,请阅读文档中有关onDestroy()方法的说明:

注意: 不要指望这种方法被称为保存数据的地方! 例如,如果某个活动正在编辑内容提供程序中的数据,那么这些编辑应该在onPause()或onSaveInstanceState(Bundle)中提交,而不是在此处。 通常实现此方法是为了释放与活动相关联的线程之类的资源 ,以便在其应用程序的其余部分仍在运行时,被破坏的活动不会留下这样的东西。 在某些情况下,系统会简单地杀死活动的托管过程,而不会在其中调用此方法(或任何其他方法),因此不应将其用于执行过程消失后要保留的内容。

所以很明显,这是一个制作清理过程的好地方。 所以你要使用onPause()onStop()方法之一。

onStop()在文档中描述如下:

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

onPause()在文档中描述如下:

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

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

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

要恢复:在onPause()方法中执行清理过程,在onResume()中执行init过程。 请记住,使用此类过程您的应用程序可能会非常慢。

希望这可以帮到你。

销毁活动是正常行为。 来自Android开发者网站

在某些情况下,您的活动会因应用程序的正常行为而被销毁,例如当用户按下“返回”按钮时…

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

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

关于你的第二个问题,这样你可以在应用程序完全关闭时运行你的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(); } } 

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

  

现在,只需在应用关闭之前在任何地方启动服务即可。

  Intent intent = new Intent(this, ExitService.class); startService(intent);