Java “如何获得安卓系统”;“绑定”;服务在重新启动配置后仍然有效
我有一个android应用程序,有一些全局状态(包括一些大的Java “如何获得安卓系统”;“绑定”;服务在重新启动配置后仍然有效,java,android,Java,Android,我有一个android应用程序,有一些全局状态(包括一些大的声音池s),需要清理,所以在回答我之前的问题后,我尝试使用服务来处理这个问题 我目前正在使用一个绑定服务,每个活动都会在onStart/onStop中绑定/解除绑定到该服务,当所有活动停止时,该服务将被解除绑定并调用onDestroy,让我释放声音池 由于活动生命周期故意重叠(新活动onStart在旧活动激发onStop之前激发),因此在活动之间导航时,始终至少有一个活动绑定,并且服务保持活动状态 但是,如果我旋转屏幕以导致配置重新启动
声音池
s),需要清理,所以在回答我之前的问题后,我尝试使用服务来处理这个问题
我目前正在使用一个绑定服务,每个活动都会在onStart
/onStop
中绑定/解除绑定到该服务,当所有活动停止时,该服务将被解除绑定并调用onDestroy
,让我释放声音池
由于活动生命周期故意重叠(新活动onStart
在旧活动激发onStop
之前激发),因此在活动之间导航时,始终至少有一个活动绑定,并且服务保持活动状态
但是,如果我旋转屏幕以导致配置重新启动,则当活动活动经历配置重新启动生命周期时,服务将解除绑定并终止
我怎样才能绕过这个问题,在重新启动时保持服务的活动性,同时在应用程序停止时仍然允许服务死亡 好吧,既然这已经被证明是一个特别困难的问题,我想我会在这里发布我的解决方案,以防有人碰到类似的问题
显然有几种方法可以实现这一点,但我使用的最简单的方法是使用一个“已启动”的服务来决定何时关闭自己。我的活动每次绑定/解除绑定到服务,在设置的时间延迟(我使用了1分钟)后,如果没有其他活动绑定,服务将自动关闭-这包括用户是否停止使用app plus以及是否存在任何致命的活动错误
关机计时器在onUnbind()
中计划,并在onStartCommand()
,onBind()
,onRebind()中取消。如果触发,它会完全关闭服务,这反过来会触发清理服务的ondestory()
中的托管状态
我的服务
代码如下:
public class LocalStateService extends Service {
/** The binder to give to clients. */
private final IBinder binder = new LocalStateBinder();
/** Used for time-delayed shutdown. */
private final Handler handler = new Handler();
/**
* Called before starting or the first binding.
*/
@Override
public void onCreate() {
// initialise state...
}
/**
* Called when this service is explicitly started.
* @param intent The intent passed on starting, unused
* @param flags Startup flags, unused
* @param startId Identifies each start request
* @return Desired restart behaviour
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
cancelShutdown();
// if killed, we would like Android to restart this service, but don't bother re-delivering
// the original intent used to start the service
return START_STICKY;
}
/**
* Called when the first client binds.
* @param intent The intent passed on binding
* @return The binding to use
*/
@Override
public IBinder onBind(Intent intent) {
cancelShutdown();
return binder;
}
/**
* Called when the first of previous clients re-binds.
* @param intent The intent passed on binding
*/
@Override
public void onRebind(Intent intent) {
cancelShutdown();
}
/**
* Called when all clients have unbound.
* @param intent The first intent originally passed on binding
* @return Whether this service should be notified of rebinding
*/
@Override
public boolean onUnbind(Intent intent) {
// post a callback to be run in 1 minute
handler.postDelayed(delayedShutdown, 1000L * 60);
// we do want onRebind called when clients return
return true;
}
@Override
public void onDestroy() {
// state cleanup...
}
private Runnable delayedShutdown = new Runnable() {
@Override
public void run() {
LocalStateService.this.stopSelf();
}
};
/**
* Cancel any shutdown timer that may have been set.
*/
private void cancelShutdown() {
// remove any shutdown callbacks registered
handler.removeCallbacks(delayedShutdown);
}
}
我的主要活动不是从我的应用程序中执行此操作,而是在onCreate()
中调用startService(..)
,因为这对于初始启动和用户返回到使用暂停的应用程序时都有效(服务可能已决定关闭,也可能尚未决定关闭)
然后,每个活动都会按照正常情况绑定和解除绑定
我发现:
- 在活动之间导航时,不会触发任何服务回调。由于活动生命周期重叠,这些是次要绑定/取消绑定
- 当活动重新启动时(例如屏幕旋转),服务将获得一个
onUnbind()
调用,然后是一个onRebind()
调用
- 暂停应用程序(例如,从主活动按home键)或完成应用程序(例如,从主活动按back键)时,服务将获得
onUnbind()
,然后计时器启动
我需要在这方面做更多的工作。我避免像瘟疫一样绑定,因此我没有一个现成的模式来解决您的问题,显然我之前给您的建议是有缺陷的。如何向我的应用程序实例添加一些绑定/取消绑定功能-增加/减少一个内部计数器,并且只实际绑定/取消绑定一次?这可能会起作用,尽管这有点危险(例如,未处理的异常导致无法递减)。另一种方法是使用“已启动”服务
,它可以决定何时需要自行关闭。然后,我可以复制活动的绑定/解除绑定,在最后一次解除绑定时关闭,但有一个方法,活动可以调用该方法来标记正在发生的配置重新启动?在不重新启动活动的情况下处理循环如何?这是一个令人耳目一新的研发。谢谢。您是否考虑从OnBand()中调用StestService(您自己)?为什么在OnBand中调用CalpSeleStutt?如何在第一个活动绑定到服务之前安排关闭?@JoeBowbeer-因为多个活动可以绑定到服务。第二个活动将使用onBind函数进入。@ScottNaef-我在实践中没有看到这一点。为了澄清,我指的是上面服务片段中对onBind/unUnbind/unreland的调用,这些调用在一个进程中运行,使用一个意图绑定多个上下文。onBind是第一次调用,除非最后一个客户端解除绑定(onUnbind),否则不会再次调用。