Android Service的两种启动方式

Service是Android的四大组件之间,可以在后台长期执行任务,但是不提供用户界面,所以我们经常会启动一个Service去执行一些需要在后台执行的任务,但是启动Service有两种方式,一种是直接start去启动,另外一种是通过bind(绑定)来启动的,下面我们就聊一聊这两种启动方式

startService

调用步骤:
1、自定义一个类TestService(类名任意取)去继承Service
2、Android四大组件都是要在Manifest.xml文件中去注册的,因此我们需要在Manifest.xml文件中加上自定的一的TestService

1
<service android:name=".TestService"></service>

3、在Activity中通过startService(Intent)来开启该服务,在其他的类中也可以通过context.startService(Intent)来调用

1
2
Intent intent = new Intent(this, TestService.class);
startService(intent);

4、在Activity中通过stopService(Intent)来停止该服务,在其他的类中也可以通过context.stopService(Intent)来停止,注意一点,服务只可以停止一次

1
2
Intent intent = new Intent(this, TestService.class);
stopService(intent);

上面的四个步骤就是通过start启动服务到stop停止服务的全过程,接下来我们再看一下这个过程中生命周期是怎样的。

当我们点击一个按钮去启动服务的时候,Log的打印如下,

1
2
08-16 10:47:56.446 5031-5031/com.hurui.ruicalendar I/TestService:: onCreate
08-16 10:47:56.448 5031-5031/com.hurui.ruicalendar I/TestService:: onStartCommand

当我们点击一个按钮去停止服务的时候,Log的打印如下,

1
08-16 10:48:05.332 5031-5031/com.hurui.ruicalendar I/TestService:: onDestroy

从Log的打印情况来看,整个生命周期的过程如下:
onCreate() –> onStartCommand()(onStrat()已经过时) –> onDestroy()

这种方式启动服务有两个特点:
1、调用者在启动该服务之后,两者便没有任何的关系了,以后无论调用者处于什么样的状态,服务还是会在后台执行
2、调用者不能去调用服务里面的方法

bindService

调用步骤:
1、同startService方法
2、同startService方法
3、在Activity中通过bindService(Intent,ServiceConnection,int)来开启该服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Intent intent = new Intent(this, TestService.class);
bindService(intent,mServiceConnection,BIND_AUTO_CREATE);
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
TestService.MyBind myBind = (TestService.MyBind) iBinder;
mTestService = myBind.getService();
Log.i("MainActivity", mTestService.getString());
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};

4、在Activity中通过unbindService(mServiceConnection)来停止该服务

1
unbindService(mServiceConnection);

上面的四个步骤就是通过start启动服务到stop停止服务的全过程,接下来我们再看一下这个过程中生命周期是怎样的。

当我们点击一个按钮去启动服务的时候,Log的打印如下,

1
2
3
08-16 11:09:50.800 13720-13720/com.hurui.ruicalendar I/TestService:: onCreate
08-16 11:09:50.800 13720-13720/com.hurui.ruicalendar I/TestService:: onBind
08-16 11:09:50.803 13720-13720/com.hurui.ruicalendar I/MainActivity: 我是TestService中的方法

当我们点击一个按钮去停止服务的时候,Log的打印如下,

1
2
08-16 11:10:02.815 13720-13720/com.hurui.ruicalendar I/TestService:: onUnbind
08-16 11:10:02.821 13720-13720/com.hurui.ruicalendar I/TestService:: onDestroy

从Log的打印情况来看,整个生命周期的过程如下:
onCreate() –> onBind() -> onUnbind() –> onDestroy()
并没有像startService中那样调用startCommand()
而且在Log还打印了“我是TestService中的方法“这句话,这句话是在TestService的getString()方法中的,说明在MainActivity中可以调用服务中的方法

1
2
3
4
5
6
7
8
public class TestService extends Service {
、、、、
public String getString(){
return "我是TestService中的方法";
}
}

总结一下bindService启动服务的两个特点:
1、服务与它的调用者一直存在关系,调用者挂了,那么服务也就是随之挂了
2、调用者可以调用服务中的方法和变量

Demo代码

下面是所有的代码:
TestService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class TestService extends Service {
private MyBind mMyBind = new MyBind();
public String sss = "aaaa";
public class MyBind extends Binder{
public TestService getService(){
return TestService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
Log.i("TestService:", "onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("TestService:", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("TestService:", "onDestroy");
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i("TestService:", "onBind");
return mMyBind;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("TestService:", "onUnbind");
return false;
}
public String getString(){
return "我是TestService中的方法";
}
}

MainActivty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button startBtn, stopBtn;
private TestService mTestService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startBtn =(Button) findViewById(R.id.bindService);
stopBtn = (Button) findViewById(R.id.unbindService);
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bindService:
startService();
break;
case R.id.unbindService:
stopService();
break;
}
}
public void startService(){
Intent intent = new Intent(this, TestService.class);
bindService(intent,mServiceConnection,BIND_AUTO_CREATE);
}
public void stopService(){
unbindService(mServiceConnection);
}
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
TestService.MyBind myBind = (TestService.MyBind) iBinder;
mTestService = myBind.getService();
Log.i("MainActivity", mTestService.getString());
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}