应用程序从最近的应用列表中删除后,Android服务崩溃

ala*_*eno 22 android android-service

我有一个由活动启动(未绑定)的服务.如果活动被破坏(例如通过按下后退按钮),则服务继续运行,这当然是有意的.但是,如果我将活动从"最近的应用"列表中滑出,则会立即重新启动该服务.这是可重现的,每次从列表中删除活动/应用程序时,都会对服务的onCreate方法进行新调用.两者之间没有调用onDestroy!

首先我认为服务被android杀死了,尽管我没有看到杀人的理由(活动和服务都没有资源消耗的东西,事实上它们是简约的,什么都不做).但后来我注意到服务实际上崩溃了.

V/MainActivity(856): onDestroy // swipe out of the list
I/ActivityManager(287): Killing 856:com.example.myapp/u0a10050: remove task
W/ActivityManager(287): Scheduling restart of crashed service com.example.myapp/.TestService in 5000ms
Run Code Online (Sandbox Code Playgroud)

代码并不值得注意,但在这里

活动:

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.v(TAG, "onCreate, starting service...");
        startService(new Intent(this, TestService.class));
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v(TAG, "onStart");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy");
    }

    //[...]
}
Run Code Online (Sandbox Code Playgroud)

服务:

public class TestService extends Service {

    private static final String TAG = "Service";

    // onBind omitted

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.v(TAG, "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy");
    }

}
Run Code Online (Sandbox Code Playgroud)

简而言之:我的服务独立于活动的生命周期,但只要我不刷掉最近的应用列表的应用程序.在这种情况下,服务重新启动但没有调用onDestroy.

每次发生这种情况时,不仅服务状态,而且服务正在进行的工作也会丢失.我只是想知道为什么滑动就是这个原因.

Dav*_*ser 21

从最近的任务列表中滑动应用程序实际上会杀死托管应用程序的操作系统进程.由于您的服务在与您的活动相同的过程中运行,因此有效地杀死了该服务.它不会调用onDestroy()该服务.它只会杀死这个过程.繁荣.死.不见了.您的服务不会崩溃.

由于您的服务START_STICKY从调用返回onStartCommand(),因此Android会识别您的服务应该重新启动并安排重新启动已终止的服务.但是,当您的服务重新启动时,它将处于新创建的进程中(您可以onCreate()在服务中看到调用),因此它必须重新开始工作.

规则#1:不要从最近的任务列表中刷过应用程序;-)

  • 不.那无济于事.我刚刚通过应用程序验证了服务在一个单独的进程中运行的位置.从最近的任务列表中轻扫应用程序也会导致托管该服务的进程.日志消息"调度崩溃服务的重新启动"只是Android中不太完美的万件事之一.如果进程消失,Android将安排重新启动服务,无论它如何发生.例如,如果您的应用程序正在运行并且您安装了更新,则安装程序需要终止该服务以安装更新.Android也在这里重新安排服务! (7认同)
  • 当我们向左滑动时,解决方案是什么来实际防止此服务崩溃? (4认同)
  • @Locutus:我无法在KitKat 4.4.4和Lollipop 5.0上重现这一点.删除任务后,我的粘性服务总是重新启动. (2认同)