Service 的使用以及绑定

在MainActivity所在包新建一个Service类,在activity_main.xml中增加4个按钮,如下

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">


<Button
android:id="@+id/btnStartService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启动服务" />

<Button
android:id="@+id/btnStopService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="停止服务" />

<Button
android:id="@+id/btnBindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" />

<Button
android:id="@+id/btnUnbindService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解除绑定服务" />

</LinearLayout>

在MainActivity中首先需要新建Intent对象,并传入Context和Service类

  • 调用startService(intent) 方法启动服务
  • 调用stopService(intent) 方法停止服务
  • 调用bindService(intent,this, Context.BIND_AUTO_CREATE) 方法绑定服务,其中第二个参数需要实现ServiceConnection接口,这里的this是MainActivity(实现了ServiceConnection接口),并重写onServiceConnected(ComponentName name, IBinder service)和onServiceDisconnected(ComponentName name)方法
  • 调用unbindService(this) 方法解除绑定,参数为实现ServiceConnection接口类

具体代码:

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
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

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

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

findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).setOnClickListener(this);
findViewById(R.id.btnBindService).setOnClickListener(this);
findViewById(R.id.btnUnbindService).setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService(intent);
break;
case R.id.btnStopService:
stopService(intent);
break;
case R.id.btnBindService:
bindService(intent,this, Context.BIND_AUTO_CREATE);
break;
case R.id.btnUnbindService:
unbindService(this);
}
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("service connect");
}

@Override
public void onServiceDisconnected(ComponentName name) {
}
}

绑定Service时需要在该Service类中onBind()的方法返回一个IBinder

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
55
56
57
58
59
public class MyService extends Service {

private boolean doPrint = false;

@Override
public IBinder onBind(Intent intent) {
return new Binder();
}

//startService 的时候执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

// new Thread(){
// @Override
// public void run() {
// while(true){
// System.out.println("服务正在运行...");
// try {
// sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }
// }.start();

System.out.println("service onStartCommand");
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
super.onCreate();
System.out.println("service onCreate");
doPrint = true;
new Thread() {
@Override
public void run() {
while (doPrint) {
System.out.println("服务正在运行...");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

}

@Override
public void onDestroy() {
super.onDestroy();
System.out.println("service onDestroy");
doPrint=false;
}
}

Service 声明周期

  • 启动服务的时候 会调用onCreate方法,同时调用onStartCommand方法
  • 停止服务会调用onDestroy方法
  • 绑定服务 会调用onCreate方法以及实现的onServiceConnected方法
  • 解除绑定 会调用onDestroy方法
  • 每次执行startService(intent)方法都会调用onStartCommand方法

    Service参数的传递

  • 启动Service传递参数

    启动service时只要将参数放入intent即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void onClick(View v) {
    switch (v.getId()){
    case R.id.btnStartService:
    Intent i = new Intent(this,MyService.class);
    i.putExtra("data",editText.getText().toString());
    startService(i);
    break;
    case R.id.btnStopService:
    stopService(new Intent(this,MyService.class));
    break;
    }
    }

    在onStartCommand方法中进行获取传递过来的参数

    1
    2
    3
    4
    public int onStartCommand(Intent intent, int flags, int startId) {
    message = intent.getStringExtra("data");
    return super.onStartCommand(intent, flags, startId);
    }
  • 绑定Service参数的传递

    首先在Myservice中定义一个自定义的Binder并集成android.os.Binder,然后在onBind的方法中返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Override
    public IBinder onBind(Intent intent) {
    return new Binder();
    }

    public class Binder extends android.os.Binder {

    public void setData(String data){
    message = data;
    }
    }

然后在绑定服务的重写方法onServiceConnected(ComponentName name, IBinder service)中的IBinder进行操作

1
2
3
4
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyService.Binder) service;
}

比如按钮点击传送数据

1
2
3
4
5
case R.id.btnSyncData:
if(binder!=null){
binder.setData(editText.getText().toString());
}
break;