Service不同启动场景的生命周期介绍

984 阅读6分钟

Service有两种启动方式,分别是:startService();bindService()。

两种启动方式对应的生命周期如下:

startService->stopService(启动服务->停止服务) : onCreate -> onStartCommand -> onDestroy

bindService->unbindService(绑定服务->解绑服务) : onCreate -> onBind -> onUnbind -> onDestroy

一.抛出问题

有没有想过这么几个问题:

如果同一个Service多次startService启动服务,它的生命周期如何?

多次bindService绑定服务,它的生命周期又如何?

如果再把两种启动方式交替执行,又交替停止服务,它的生命周期又是怎样的?

Service生命周期.png

二.准备工作

带着这几个问题,可以代码验证一下。

准备工作,先撸出来startService,bindService,stopService,unbindService执行代码。

startService:

Intent intent = new Intent(MainActivity.this, FirstService.class);
startService(intent);

bindService

Intent intent = new Intent(MainActivity.this, FirstService.class);
bindService(intent,conn, BIND_AUTO_CREATE);

stopService

Intent service = new Intent(MainActivity.this, FirstService.class);
stopService(service);

unbindService

unbindService(conn);

最后附上绑定服务解绑服务需要的ServiceConnection,也就是上面代码中的conn:

private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
        Log.d(TAG, "onServiceConnected "+name);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d(TAG, "onServiceDisconnected "+name);
    }

    @Override
    public void onBindingDied(ComponentName name) {
        Log.d(TAG, "onBindingDied "+name);
    }

    @Override
    public void onNullBinding(ComponentName name) {
        Log.d(TAG, "onNullBinding "+name);
    }
};

核心操作代码如上,当然还要在FirstService.class类中打印相关生命周期回调方法的log信息,方便验证执行逻辑。 注意FirstService.class需要继承Service:FirstService extends Service

清单AmdroidManifest文件注册FirstService组件<service android:name=".service.FirstService"/>

三.执行操作,查看Log信息

操作:启动服务 -> 停止服务 startService->stopService

2021-08-04 17:21:33.205 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:21:33.207 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartCommand Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:21:33.207 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartIntent { cmp=com.example.myfirstproject/.service.FirstService }
-------stopService-------
2021-08-04 17:22:00.170 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

没什么说的,简单的启动服务,停止服务的生命周期:onCreate -> onStartCommand -> onDestroy


操作:绑定服务 -> 解绑服务 bindService->unBindService

2021-08-04 17:22:46.916 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:22:46.918 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onBind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:22:46.942 27757-27757/com.example.myfirstproject D/MainActivity-TEST_SERVICE: onNullBinding ComponentInfo{com.example.myfirstproject/com.example.myfirstproject.service.FirstService}
--------onUnbindService----
2021-08-04 17:23:26.428 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onUnbind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:23:26.429 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

同样,简单的绑定服务,解绑服务的生命周期: onCreate -> onBind -> onUnbind -> onDestroy


操作:启动服务 -> 启动服务 -> 停止服务 startService->startService->stopService:

2021-08-04 17:24:23.657 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:24:23.675 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartCommand Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:24:23.675 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartIntent { cmp=com.example.myfirstproject/.service.FirstService }
-------startService-------
2021-08-04 17:24:45.667 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartCommand Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:24:45.668 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartIntent { cmp=com.example.myfirstproject/.service.FirstService }
-------stopService-------
2021-08-04 17:25:19.052 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

多次启动服务,不会重新创建Service(onCreate).

生命周期:onCreate -> onStartCommand -> onStartCommand -> onDestroy


操作:绑定服务 -> 绑定服务 -> 解绑服务 bindService->bindService->unBindService

2021-08-04 17:25:51.741 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:25:51.773 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onBind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:25:51.783 27757-27757/com.example.myfirstproject D/MainActivity-TEST_SERVICE: onNullBinding ComponentInfo{com.example.myfirstproject/com.example.myfirstproject.service.FirstService}
--------bindService----
2021-08-04 17:26:15.197 27757-27757/com.example.myfirstproject D/MainActivity-TEST_SERVICE: onNullBinding ComponentInfo{com.example.myfirstproject/com.example.myfirstproject.service.FirstService}
--------onUnbindService----
2021-08-04 17:26:50.697 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onUnbind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:26:50.698 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

同样多次绑定服务,不会重新走onCreate和onBind,同绑定服务 -> 解绑服务生命周期一样。

生命周期: onCreate -> onBind -> onUnbind -> onDestroy


操作:这里两种操作一起讲,只有startService和bindService先后执行顺序不一样,结束都是先解绑,在停止服务。

startService->bindService->unBindService->stopService:

bindService->startService->unBindService->stopService:

先启动后绑定:startService->bindService

2021-08-04 17:27:32.271 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:27:32.272 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartCommand Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:27:32.272 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartIntent { cmp=com.example.myfirstproject/.service.FirstService }
--------bindService----
2021-08-04 17:27:44.858 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onBind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:27:44.876 27757-27757/com.example.myfirstproject D/MainActivity-TEST_SERVICE: onNullBinding ComponentInfo{com.example.myfirstproject/com.example.myfirstproject.service.FirstService}

先绑定后启动:bindService->startService

2021-08-04 17:33:13.591 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onCreate
2021-08-04 17:33:13.592 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onBind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:33:13.594 27757-27757/com.example.myfirstproject D/MainActivity-TEST_SERVICE: onNullBinding ComponentInfo{com.example.myfirstproject/com.example.myfirstproject.service.FirstService}
------startService-----------
2021-08-04 17:33:17.349 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartCommand Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:33:17.349 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onStartIntent { cmp=com.example.myfirstproject/.service.FirstService }

先后顺序不一样,总结一点就是Service创建了onCreate后都不会创建。

先解绑后停止服务:unBindService->stopService

--------onUnbindService----
2021-08-04 17:33:24.889 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onUnbind Intent { cmp=com.example.myfirstproject/.service.FirstService }
-------stopService-------
2021-08-04 17:33:29.542 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

操作:还是两种操作一起讲,只有startService和bindService先后执行顺序不一样,结束都是先停止,在解绑服务。

startService->bindService->stopService->unBindService

bindService->startService->stopService->unBindService

启动方式生命周期同上面一样,这里主要看下结束的日志信息:

先停止服务,再解绑服务 stopService->unBindService

-------stopService-------
无log
--------onUnbindService----
2021-08-04 17:32:07.340 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onUnbind Intent { cmp=com.example.myfirstproject/.service.FirstService }
2021-08-04 17:32:07.341 27757-27757/com.example.myfirstproject D/FirstService-TEST_SERVICE: onDestroy

也就是stopService操作后没有生命周期回调log,看起来没有起作用。但是在解绑服务时候会先onUnbind,然后onDestory,需要注意一点,查看上面先先解绑后停止服务,可以看出解绑只会调用onUnbind,在执行停止服务时候回调onDestory,但是如果在unBindService之前调用过了stopService,则Service还会调用onDestory。看起来先stopService没起作用,但是应该内部表面这个Service已经跟StartService没关系,只受onBind影响了。

四.总结归纳

1、多次startService不会重新onCreate.多次bindService不会重新onBind。

2、不管先startService还是bindService.

如果是stopService先于onUnbindService,则service不会立即onDestroy.只有在onUnbindService时候依次调用onUnbind.onDestroy。

如果是onUnbindService先于stopService,则service在调用onUnbindService时候调用onUnbind,最后执行stopService调用onDestroy。