- Service(服务)在Android 中是在后台运行的。服务的运行不需要任何用户界面。
启动服务有两种方式,分别是startService和bindService。
下面我们就来介绍一下startService和bindService的用法和区别。
startService
创建一个工程ServiceTest,布局文件中添加两个按钮,一个开启服务,一个停止服务。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http:///apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开启服务" />
<Button
android:id="@+id/btn_stop_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="停止服务" />
</LinearLayout>
创建一个类MyService继承Service。然后重写其onCreate(),onStartCommand(),
onDestroy()方法,在方法中加入Log打印日志。如下:
public class MyService extends Service {
public static final String TAG = "MyService";
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
//在服务创建的时候调
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate ......");
}
//在每次服务启动的时候调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand ......");
return super.onStartCommand(intent, flags, startId);
}
//在服务销毁的时候调用。
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy ......");
}
}
当然,别忘了在Manifest.xml文件中配置。
<service android:name=".MyService"></service>
MainActivity中代码如下。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_start_service;
private Button btn_stop_service;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start_service = (Button) this.findViewById(.btn_start_service);
btn_stop_service = (Button) this.findViewById(.btn_stop_service);
btn_start_service.setOnClickListener(this);
btn_stop_service.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case .btn_start_service:
Intent intent = new Intent(this,MyService.class);
//开启服务
startService(intent);
break;
case .btn_stop_service:
Intent intent2 = new Intent(this,MyService.class);
//停止服务
stopService(intent2);
break;
}
}
}
运行程序到模拟器上,点击 开启服务按钮,然后到设置--> 应用 -->正在运行 查看,效果如下。
MyService中的onCreate()和 onStartCommand()方法都执行了,日志如下:
1555-1555/com.example.servicetest D/MyService: onCreate ......
1555-1555/com.example.servicetest D/MyService: onStartCommand ......
然后再点击多次开启服务按钮,发现只有onStartCommand()方法执行了。
点击停止服务按钮,onDestroy()方法已经执行了。
查看 设置--> 应用 -->正在运行 发现服务已经被销毁了。
- 小总结,使用startService开启服务的方式,可以使服务长期运行在后台。
bindService
前边我们介绍了startService,下面我们来聊一聊bindService。
往布局文件中添加2个按钮。
<Button
android:id="@+id/btn_bind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="绑定服务" />
<Button
android:id="@+id/btn_unbind_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解绑服务" />
修改MyService中代码,创建MyBinder类继承BInder,并自定义一个startGame()方法,打印Log。
并将MyBinder 的实例对象在onBind()方法中返回回去。
private MyBinder myBinder = new MyBinder();
class MyBinder extends Binder{
public void startGame(){
Log.d(TAG,"我是服务里边的方法,startGame ......");
}
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
MainActivity中使用bindService需要借助到ServiceConnection这个类。
重写其绑定成功onServiceConnected()和绑定失败onServiceDisconnected()的方法。
并将onServiceConnected()方法中的service强转为自己写的MyBinder,并调用startGame()方法。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_start_service;
private Button btn_stop_service;
private Button btn_bind_service;
private Button btn_unbind_service;
private MyService.MyBinder myBinder;
boolean flag = false;
private ServiceConnection connection = new ServiceConnection() {
//成功绑定的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//强转
myBinder = (MyService.MyBinder) service;
//调用服务里边的方法
myBinder.startGame();
flag = true ;
}
/**
* 连接正常关闭的情况下是不会被调用的,
* 该方法只在Service 被破坏了或者被杀死的时候调用。
*/
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start_service = (Button) this.findViewById(.btn_start_service);
btn_stop_service = (Button) this.findViewById(.btn_stop_service);
btn_bind_service = (Button) this.findViewById(.btn_bind_service);
btn_unbind_service = (Button) this.findViewById(.btn_unbind_service);
btn_start_service.setOnClickListener(this);
btn_stop_service.setOnClickListener(this);
btn_bind_service.setOnClickListener(this);
btn_unbind_service.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case .btn_start_service:
Intent intent = new Intent(this,MyService.class);
//开启服务
startService(intent);
break;
case .btn_stop_service:
Intent intent2 = new Intent(this,MyService.class);
//停止服务
stopService(intent2);
break;
case .btn_bind_service:
Intent bindIntent = new Intent(this, MyService.class);
// 绑定服务
bindService(bindIntent,connection,BIND_AUTO_CREATE);
break;
case .btn_unbind_service:
if (flag){
//解绑服务
unbindService(connection);
flag = false;
}
break;
}
}
}
运行程序,点击绑定服务按钮,发现MyBinder中的startGame()方法已经被调用了。
5829-5829/com.example.servicetest D/MyService: onCreate ......
5829-5829/com.example.servicetest D/MyService: 我是服务里边的方法,startGame ......
多次点击 绑定服务按钮 ,发现Log信息并没有变化,说明只能绑定一次。
查看 设置--> 应用 -->正在运行 发现服务并没有被创建。
然后点击 解绑服务 按钮 ,执行了onDestroy()方法。
- 小总结,bindService只能调用服务中的方法,不能启动服务让其长期运行在后台。
startService和bindService组合使用
经过上边的例子,我们已经了解了两者的区别,那么现在我有个想法,
我既想让服务长期运行在后台,又想调用服务里边的方法,该怎么办呢?
我们可以将startService和bindService组合到一起来使用。
还是使用刚才那个例子,运行程序。
先点击 开启服务按钮, 再点击 绑定服务按钮 ,Log如下。
查看 设置--> 应用 -->正在运行 发现服务已经被创建了。
我们想要的功能就实现了,既让服务运行在后台,又调到了服务里边的方法。
销毁服务的时候需要 点击解绑服务 的按钮才可以销毁服务。
以上就是startService和bindService的用法和区别。如有错误请指出,谢谢!