Android - 跨多个活动管理本地服务绑定/解除绑定的有效方法
从 API 级别 4 及以上级别进行定位和构建。
现在,我正在处理一个问题,其中我试图跨多个活动维护与本地服务的绑定,并在最后一个连接解除绑定时停止服务。
简而言之,我的服务只是调用 HandlerThread 中的系统服务,该系统服务快速返回到 BroadcastReceiver,然后在等待预定时间(至少 15 秒)后再次执行相同的调用。
假设我让我的基本活动以这种方式在 onCreate() 中创建到我的服务的第一个绑定:
Intent service = new Intent(ActivityA.this, MyLocalService.class);
getApplicationContext().bindService(service, mConnection, BIND_AUTO_CREATE);
还假设由于我通过继承活页夹和连接来维持跨屏幕旋转的绑定,所以我不会从服务直至活动结束: //onRetainNonConfigurationInstance 继承了我的活页夹和连接,因为我是从应用程序上下文绑定的,所以它们是公平的游戏。
public void onDestroy(){
super.onDestroy();
//using binder, remove callback to service from current activity
if(isFinishing(){
getApplicationContext().unbindService(mConnection);
}
}
我几乎为任何其他想要监听该服务的 Activity 进行此设置。
我的问题是,最终,某些活动不会立即取消绑定,因此如果服务是自动创建的,服务仍将按照绑定/取消绑定模式的行为挂起。在解除对最后一个活动的绑定之前,我必须停止线程,这会阻止在 BG 中调用任何系统服务。有没有更好的方法来管理绑定和取消绑定服务,或者我是否在当前设置中尽力而为?另外,由于我的服务(通过活页夹)是弱引用的,这会降低我泄漏内存的风险吗?
Targeting and building from API Level 4 and above.
Right now, I'm dealing with an issue in which I'm trying to maintain bindings to my local service across multiple activities, and stop the service when the last connection is unbound.
In a nutshell, my service just calls a system service in a HandlerThread that returns quickly to a BroadcastReceiver, then does that same call again after waiting a pre-determined amount of time (at least 15 seconds).
Suppose I have my base activity create the first bond to my service in onCreate() in this fashion:
Intent service = new Intent(ActivityA.this, MyLocalService.class);
getApplicationContext().bindService(service, mConnection, BIND_AUTO_CREATE);
Suppose also that due to the fact that I maintain my binding across screen rotations by carrying over the binder and connection, I do not unbind from the service until the activity is finished:
//onRetainNonConfigurationInstance carries over my binder and connection since i bound from the app context, so they are fair game.
public void onDestroy(){
super.onDestroy();
//using binder, remove callback to service from current activity
if(isFinishing(){
getApplicationContext().unbindService(mConnection);
}
}
I pretty much do this setup for any other Activity that wants to listen in on the service.
My problem is that eventually, some activities don't unbind instantly, hence the service will still hang around as per the behavior of the bind/unbind pattern if the service is auto created. I had to go as far as stopping my thread before unbinding on the last activity, which prevented any system services being called in the BG. Is there a better way to manage binding and unbinding services, or am I doing my best with my current setup? Also, since my service (via the binder) is weakly referenced, would this reduce my risk of leaking memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
显然,它没有取消注册,因为我没有跨旋转传递绑定,并且我使用内部状态标志来确定活动是否正在旋转(当 onRetainNonConfigurationInstance() 时设置为 true称为)。在大多数情况下,它没有在 onDestroy() 中正确读取状态。
当 onDestroy() 中 isFinishing() 解析为 true 时,我最终解除绑定,并通过 onRetainNonConfigurationInstance() 传递绑定,因此,服务能够在最后一次解除绑定时关闭。
Apparently, it wasn't un-registering due to the fact that I was not passing the binding across rotations and that I was using an internal state flag to determine whether or not the activity was rotating (was set to true when onRetainNonConfigurationInstance() was called). In most cases, it was not reading the state properly in onDestroy().
I ended up unbinding when isFinishing() resolved to true in onDestroy() as well as passing the bindings through onRetainNonConfigurationInstance(), and as a result, the service was able to shut down on the last unbinding.