android - 避免在屏幕旋转时终止并重新启动服务

标签 android multithreading android-service

我正在开发一个使用服务来执行异步操作的 Android 应用程序。

目前,我一直遵循推荐的模式在 UI 关闭时解除绑定(bind)服务

onStart(){
    context.bindService();
}

onResume(){
    serviceConnection.registerCallback(this); //register/unregisterCallback is defined in my domain
    checkServiceForPendingUIActionsToRequestUser();
}

onPause(){
    serviceConnection.unregisterCallback(this);
}

onStop(){
    context.unbindService();
}

这种方法的问题有两个:

  • 当我旋转设备以测试不同布局时,正确执行了一个解除绑定(bind)/绑定(bind)循环,最终我看到服务将自身重置为原始状态
  • 该服务旨在在未显示 UI 时发布通知以引起用户的注意以执行操作:当用户点击通知时,UI 应该检查服务状态并需要适当的输入(长-named 方法),但是我可以看到该服务再次重置为其原始状态

注释掉 unbindService() 调用以保持服务处于 Activity 状态并不是一个好习惯,但无论如何我必须保持我的服务(在不等待输入时也作为前台运行)处于 Activity 状态至少在屏幕旋转完成之前。

有什么想法吗?

最佳答案

选项 #1:不要使用绑定(bind)模式,而是使用命令模式(startService()stopService()stopSelf( )).

选项#2。在保留的 fragment 中绑定(bind)到 Application 上下文,当 fragment 本身被销毁时解除绑定(bind)。保留的 fragment 存在于配置更改中。 Application 上下文避免了与保留跨配置更改的绑定(bind)相关的一个可能的内存泄漏区域。

This sample project演示选项#2。在我的 DownloadFragment 中,我绑定(bind)到 onAttach() 中的服务:

  @Override
  public void onAttach(Activity host) {
    super.onAttach(host);

    appContext=(Application)host.getApplicationContext();
    appContext.bindService(new Intent(getActivity(),
                                      DownloadService.class), this,
                            Context.BIND_AUTO_CREATE);
  }

( fragment 本身也作为 ServiceConnection)

然后我在 onDestroy() 中解除绑定(bind):

  @Override
  public void onDestroy() {
    appContext.unbindService(this);
    disconnect();

    super.onDestroy();
  }

关于android - 避免在屏幕旋转时终止并重新启动服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26958478/

相关文章:

android - 停止 OnMyLocationChangeListener

java - 方法必须从UI线程调用,当前推断的线程是worker

android - 线程启动/停止在 Android 上无法正常工作

c++ - wxHTTP 和线程

android - AlarmManager 而不是后台服务?对于重复任务

c# - 如何在运行时在 Xamarin Android 中执行 C# 代码?

android - 短信收件箱中的日期格式

Android服务在应用程序被杀死后停止

android - 防止服务被杀死

android - Firebase 版本 9.2.1 是否可用?