在定位更改期间保持服务运行

在我的应用程序中,我有一个Service负责照看到外部设备的蓝牙连接。 此Service类会定期轮询外部蓝牙设备的数据,并将最新的数据添加到高速caching(或可能SD卡)内存中的日志中。

在我有的各种Activity类中,有一个代表主UI的特定Activity 。 它负责以graphicsforms显示基于caching文件数据的logging数据。 我们把这个Activity称为Dashboard 。 用户可以在该图上来回滚动,以查看自应用程序启动以来收集并logging在caching中的数据。

为了这个问题的目的,有两种操作模式需要考虑。 用户可以select“login到SD卡”选项,即使所有的Activity类都被终止,应用程序也必须继续轮询和logging到SD卡(例如,用户已经回到启动器)。 在这种情况下,我的Service将使用.startService()启动并继续运行,并且只有在用户再次调用应用程序并禁用SD卡日志时才会停止。 另一种模式是用户没有select“login到SD卡”,在这种情况下, Service仍在pipe理蓝牙连接,轮询和logging到缓冲存储器,目的是直观地显示graphics上的数据,但只有在使用Dashboard Activity时需要这样做。

我现在所拥有的是Dashboard Activity最初使用bindService()绑定到Service ,并在onPause()方法中进行相应的unbindService()调用(否则我会泄露该Service )。

问题在于Service需要维护蓝牙连接,并在方向更改期间或用户调用另一个Activity (例如,检查电子邮件)时继续进行日志logging。 现在,如果用户select“login到SD卡”导致调用startService()那么当然没有问题。 问题当然是如何区分由于方向(或其他configuration)改变而被销毁然后再创build的Activity ,并且由于用户返回到启动器而被销毁。 在前一种情况下,我不希望Service数据logging被中断。 在后一种情况下, 如果用户没有select“login到SD卡”,我希望Service停止。

我现在所能想到的最好的解决scheme是使用startService() 始终启动服务,以便在Dashboard被销毁后继续运行。 然后我会做的是在Service实现超时, 除非启用持续的SD卡logging, 否则 Service将自行停止, 或者 Dashboard在5秒内(例如)再次创build并重新绑定到Service 。 这似乎有点粗糙,我不禁认为这是一个常见的devise问题,有一个更好的解决scheme,我忽略了。

Related of "在定位更改期间保持服务运行"

您可以使用的一种方法是在onPause()解除绑定之前检查活动是否为onPause() 。 如果正在完成,您将推迟解除绑定到您的onDestroy()方法。 然而,在调用onDestroy()之前,可以将ServiceConnection保存在onRetainNonConfigurationInstance()方法中。 如果你确实执行了这个持久化,那么你根本就不会在你的onDestroy()里调用unBind() ,而只是让你的Activity的新实例解除绑定。

这就是说,根据您的应用程序,您可能会发现启动/停止服务更容易。

scheme1:如果你想要的服务被销毁,立即当主要活动结束。

绑定之前手动启动时,服务不会被销毁:

 protected void onStart() { Intent intent = new Intent(getApplicationContext(), MServcie.class); startService(intent); bindService(intent, connection, Context.BIND_AUTO_CREATE); } 

只有在您的活动完成后才能停止服务!

 protected void onStop() { if (service != null) { unbindService(connection); service = null; if (isFinishing()) { stopService(new Intent(getApplicationContext(), MyServcie.class)); } } } 

选项2:如果你想让操作系统决定服务何时停止。

 protected void onStart() { Intent intent = new Intent(this, MServcie.class); getApplicationContext().bindService(intent, this, Context.BIND_AUTO_CREATE); } 

正如你可能已经知道,一个服务是真的有一个独立的生命周期活动。 因此,您可以考虑不使用纯粹的监控scheme的服务。 您只需要一个与后台案例中的“活动”分开的生命周期,而不是纯粹的监控案例。

真正想要的是将您的日志logging与您的应用程序的生命周期绑定在一起,并且您可以通过启动/停止活动或您的服务来控制应用程序的生命周期。 如果您在可从Application对象访问的单独线程中执行了轮询,则您的活动无需与服务进行绑定,只需与此日志logging线程进行通信即可。 当你想要后台日志logging,你可以启动/停止服务,这也将与日志线程通信,以优雅地停止清理,正确的重启等。

你应该使用isChangingConfigurations() ,而不是isFinishing() :后者是false ,在一个活动失去知名度和configuration改变的情况下,所以你不能区分。