Android Service 生命周期

本文详细探讨了Android Service的生命周期,包括启动service的各种情况及其生命周期变化,如startService和bindService的不同组合。还分析了结束service的方式,如stopService和unbindService的影响。此外,文章提到了ServiceConnection的重要性和注意事项,帮助开发者理解和掌握Service的正确使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

Android Service的生命周期比activity要简单,很多android开发同学,都可以脱口而出,但service生命周期又很混乱,因为其生命周期并不是一成不变的。所以又有时我们会傻傻分不清楚。所以我们在这里用几个例子把service的生命周期彻底搞清楚。

目录

Service的生命周期

service的生命周期有哪些呢?

这里写图片描述

  1. onCreate : 当Service被创建时执行
  2. onStartCommand:当执行startService时被调用
  3. onStart:已经被onStartCommand代替,在本文中,将不在讨论onStart。
  4. onBind:当执行bindService时被调用。
  5. onUnbind:当执行unbindService是被调用
  6. onDestroy:当Service被销毁时被调用

    这几个生命周期大家应该都清楚,但我们很难像Activity一样把这些生命周期串在一起。因为在不同的情况下。生命周期的会有不同的组合方式,下面我们举个栗子来分析一下。

举个栗子

栗子来了,首先我们有一个这样的MainActivity

这里写图片描述

Activity中有四个Button 分别是
1. startService 启动service
2. bindService 绑定service
3. stopService 停止service
4. unbindService 解绑service

MainActivity的代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private ServiceConnection serviceConnection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        serviceConnection = new MainServiceConnection();

        findViewById(R.id.btn_start_service).setOnClickListener(this);
        findViewById(R.id.btn_bind_service).setOnClickListener(this);
        findViewById(R.id.btn_stop_service).setOnClickListener(this);
        findViewById(R.id.btn_unbind_service).setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start_service:
                Intent startIntent = new Intent(this, MainService.class);
                startService(startIntent);
                break;
            case R.id.btn_bind_service:
                Intent bindIntent = new Intent(this, MainService.class);
                bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
                break;
            case R.id.btn_stop_service:
                Intent stopIntent = new Intent(this, MainService.class);
                stopService(stopIntent);
                break;
            case R.id.btn_unbind_service:
                unbindService(serviceConnection);
                break;
        }
    }

    private class MainServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("testService", TAG + " onServiceConnected()");
        }

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

代码很简单,我们分别为四个Button设置了四个点击事件,分别是:

  1. startService(startIntent);
  2. bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
  3. stopService(stopIntent);
  4. unbindService(serviceConnection);

还有MainService的代码如下:

public class MainService extends Service {

    private static final String TAG = MainService.class.getSimpleName();

    private MyBinder myBinder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("testService", TAG + " onCreate()");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("testService", TAG + " onBind()");
        return myBinder;
    }

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

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d("testService", TAG + " onUnbind()");
        return super.onUnbind(intent);
    }

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

    public class MyBinder extends Binder {

        public MainService getService() {
            return MainService.this;
        }
    }
}

MainService就是被MainActivity启动的service,在这个类里我们将Service的主要生命周期打印了出来。下面问题来了

问题一 启动service的生命周期是怎样的呢

我们知道启动一个Service有两种方法分别是startService 和 bindService 那么我们提出一个问题。当我们分别执行以下四种情况,生命周期会是怎样的呢。

我们分别点击:

这里写图片描述

怎么样,心理有答案了么?

情况一 :点击两次startService

log输出如下所示:

这里写图片描述

再画个图来示意一下:

这里写图片描述

service首次启动时会先回调onCreate,然后回调onStartCommand。当第二次启动Service时,因为这时Service已经被Create过,所以只回调onStartComment。同样,当第三次执行onStart时依然只会回调onStartComment。

情况二:点击startService——>bindService

log输出如下所示:

这里写图片描述

生命周期示意图如下:

这里写图片描述

跟之前一样,在执行startService时,会回调onCreate和onStartCommand,而当执行bindService时会回调onBind函数。

情况三:点击两次bindService

log输出如下所示:

这里写图片描述

生命周期示意图如下:

这里写图片描述

首次点击bindService时会执行onCreateService(我们在bindService时使用了参数BIND_AUTO_CREATE如字面意思,在绑定service时会自动创建service)和onbind,但是再次执行bindservice,我们发现没有任何效果的。

bindService是将MainActivity和MianService绑定到一起,但当两个对象已经绑定之后,重复绑定也就没有任何意义了。

情况四:点击bindService——>startService

log输出如下所示:

这里写图片描述

生命周期示意图如下:

这里写图片描述

执行bindService后,会回调onCreate 和 onbind,再执行startService后会回调onStartCommend。

问题二 结束service的生命周期又是怎样的呢

结束service可以通过unbindService和StopService来实现。在不同的情况下,执行这两条命令,会得到不同的生命周期,接下来我们不在截图日志输出了,直接用框图来一一列举不同的生命周期。

stopService

这里写图片描述

情况一:
我们执行startService后执行stopService会回调onDestroy函数

情况二:
我们执行bindService后执行stopService会发现没有反应

情况三:
当我们执行startService和bindService后执行stopService发觉没有反应

unbindService

这里写图片描述

情况一:
我们执行bindService后执行unbindService会回调onUnbind和onDestroy

情况二:
当我们执行startService后执行unbindService发现崩溃了。。。。。

情况三:
当我们执行startService和bindService后执行unbindService,只会回调onUnbind

特殊情况

这里写图片描述

情况一:
当执行startService和bindService后执行unbindService会回调onBind函数,在调用stopService后会回调onDestroy函数。

情况二:

当执行startService和bindService后执行stopService看似没反应,这里之所以说看似没反应,是因为,他实际导致生命周期的变化。原本点击onUnbindService后只会回调onUnbind但这是同时回调了onDestroy函数。这里我们可以得出结论,在执行stopService时并非真的没有效果,程序只是将执行情况记录下来,并在执行onUnbindService时体现了出来。

问题三 ServiceConnection

private class MainServiceConnection implements ServiceConnection {

       @Override
       public void onServiceConnected(ComponentName name, IBinder service) {
           Log.d("testService", TAG + " onServiceConnected()");
       }

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

在bindService时,我们都需要传入一个实现了接口ServiceConnection的对象,里面有两个监听函数。这里需要说明一下

1、当bindService成功是会回调onServiceConnected

2、当unbindService成功之后 不会、不会、不会!!!执行onServiceDisconnected,是不是很坑,这里只有当service意外停止,导致disconnected时才会回调。

总结一下

上面说了那么多,是不是已经晕了,怎么记啊???不要着急,下面就来总结一下,只要记住以下结论,就不会用错了。

  1. 首次启动Service时会回调onCreate函数,并且在整个生命周期中只回调一次。
  2. 每次调用startService都会回调一次onStart函数。
  3. bindService只能绑定一次,再次绑定回无效。
  4. startService和stopService应该成对出现,即有startService就应该有stopService
  5. bindService和unbindService应该成对出现,及有bindService就应该有unbindeServcie。切忌,unbindService单独出现会崩溃
  6. onServiceDisconnected并不是在执行unbindService时回调的,是在Service意外停止时回调的。

好了Service的生命周期就介绍到这里了。有问题欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值