Android Service 生命周期

来源:互联网 发布:java poi 导出xlsx 编辑:程序博客网 时间:2024/06/10 09:45

简介

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

目录

  • 简介
  • 目录
  • Service的生命周期
  • 举个栗子
  • 问题一 启动service的生命周期是怎样的呢
    • 情况一 点击两次startService
    • 情况二点击startServicebindService
    • 情况三点击两次bindService
    • 情况四点击bindServicestartService
  • 问题二 结束service的生命周期又是怎样的呢
    • stopService
    • unbindService
    • 特殊情况
  • 问题三 ServiceConnection
  • 总结一下

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的生命周期就介绍到这里了。有问题欢迎指正

0 0
原创粉丝点击