您的位置:首页 > 移动开发 > Android开发

Android Service 生命周期

2017-03-25 23:38 183 查看

简介

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

目录

简介

目录

Service的生命周期

举个栗子

问题一 启动service的生命周期是怎样的呢
情况一 点击两次startService

情况二点击startServicebindService

情况三点击两次bindService

情况四点击bindServicestartService

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

unbindService

特殊情况

问题三 ServiceConnection

总结一下

Service的生命周期

service的生命周期有哪些呢?



onCreate : 当Service被创建时执行

onStartCommand:当执行startService时被调用

onStart:已经被onStartCommand代替,在本文中,将不在讨论onStart。

onBind:当执行bindService时被调用。

onUnbind:当执行unbindService是被调用

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设置了四个点击事件,分别是:

startService(startIntent);

bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);

stopService(stopIntent);

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时才会回调。

总结一下

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

首次启动Service时会回调onCreate函数,并且在整个生命周期中只回调一次。

每次调用startService都会回调一次onStart函数。

bindService只能绑定一次,再次绑定回无效。

startService和stopService应该成对出现,即有startService就应该有stopService

bindService和unbindService应该成对出现,及有bindService就应该有unbindeServcie。切忌,unbindService单独出现会崩溃

onServiceDisconnected并不是在执行unbindService时回调的,是在Service意外停止时回调的。

好了Service的生命周期就介绍到这里了。有问题欢迎指正
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android开发 service