如何在Android应用关闭或失去焦点时调用方法?
因为我正在构建的应用程序将处理相当敏感的数据,我希望每次用户登录时都将SQLite数据库与服务器同步,并在每次应用程序失去焦点时删除emty数据库(因为用户移动到主屏幕或另一个应用)。
看到Activity生命周期 ,我的想法是通过清空每个Activity的onDestroy中的数据库来做到这一点。 为了测试所描述的生命周期,我只是覆盖所有生命周期方法(onCreate,onStart,onResume,onPause,onStop和onDestroy),在其中包含一些日志消息,并启动我的应用程序。
日志消息包含在我的SettingsActivity中。 当我进入我的应用程序并移动到设置时,它运行onCreate,onStart和onResume(如预期的那样)。 然后,当我单击一个设置并移动到下一个屏幕时,它将在onPause和onStop上运行(仍然按预期方式)。 要返回到设置屏幕,我单击后退按钮,它再次运行onStart和onResume(仍然按预期),当我现在再次单击后退按钮以返回到初始屏幕时,它(令我惊讶的是)运行onPause, onStop AND onDestroy。
所以我的问题;
- 为什么在应用程序未完成时会破坏活动?
- 更重要的是:当应用程序关闭或失去焦点时,如何运行我的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);