为什么要出现绑定服务?
普通的服务activity启动后就不管了,这是活动的作用就是启动一个服务或停止一个服务,和服务的关系不够紧密,如果想让活动随时可以控制服务做事情,这时就要用到绑定服务了。
注意:
通过startService开启的服务,在服务中会执行onStartCommand函数。如果需要做耗时操作,需要在onStartCommand中开启一个新的线程来处理。为什么要在新的线程中处理耗时操作呢?因为默认服务是运行在主线程中的,也就是UI线程中,这样会导致阻塞UI线程,这一点很关键。
通过bindService开启的服务,在服务中不会执行onStartCommand函数,而是执行onBind方法,此方法返回一个继承自Binder的类,继承类中提供一个方法可以获取服务类的实例。在活动中得到服务的实例就可以调用服务中的方法,这样就可以实现活动中控制服务做事情了。
下面通过一个演示demo来实现一个绑定服务和解绑服务的功能。
先说打印的日志-主要是观察服务中的函数调用顺序及执行了哪些函数
02-18 11:21:31.563 13550-13550/com.mobile.cdtx.blog I/MyBindService: MyBindService:
02-18 11:21:31.563 13550-13550/com.mobile.cdtx.blog I/MyBindService: onCreate:
02-18 11:21:31.563 13550-13550/com.mobile.cdtx.blog I/MyBindService: onBind:
02-18 11:21:31.593 13550-13550/com.mobile.cdtx.blog I/MyBindService: seeMovie:
02-18 11:21:31.593 13550-13550/com.mobile.cdtx.blog I/MyBindService: listenMusic:
以上数据是启动服务后打印的日志,说明调用了onBind但是没有调用onStartCommand函数。其中seeMovie和 listenMusic是活动中调用了服务中的方法打印的日志
下面再看下解绑服务打印的日志:
02-18 11:22:00.563 13550-13550/com.mobile.cdtx.blog I/MyBindService: onUnbind:
02-18 11:22:00.563 13550-13550/com.mobile.cdtx.blog I/MyBindService: onDestroy:
以上数据说明执行解绑操作时,先执行了onUnbind,然后执行了onDestroy.
绑定服务和解绑服务关键的两个API就是:
bindService和unbindService
下面贴一下测试代码:
activity_bind_service.xml
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import com.mobile.cdtx.blog.R;
import com.mobile.cdtx.blog.main.service.MyBindService;
public class BindServiceActivity extends AppCompatActivity implements View.OnClickListener{
Button btnBind,btnUnbind;
MyBindService myBindService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind_service);
//控件初始化
initView();
}
//控件的初始化
private void initView(){
btnBind = (Button)findViewById(R.id.id_btn_bind);
btnUnbind = (Button)findViewById(R.id.id_btn_unbind);
btnBind.setOnClickListener(this);
btnUnbind.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.id_btn_bind:
bindService();
break;
case R.id.id_btn_unbind:
unBindService();
break;
default:
break;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
MyBindService.LocalBinder binder = (MyBindService.LocalBinder) service;
myBindService = binder.getService();
//调用服务中的方法
myBindService.seeMovie();
myBindService.listenMusic();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
//绑定服务
private void bindService(){
Intent intent = new Intent(this, MyBindService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
//解绑服务
private void unBindService(){
unbindService(mConnection);
}
}
/**
* Created by wangwentao on 2017/2/18.
* 用途:绑定服务中需要实现的接口
*/
public interface ServiceInterface {
void seeMovie();
void listenMusic();
}
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.mobile.cdtx.blog.main.interfaces.ServiceInterface;
public class MyBindService extends Service implements ServiceInterface{
private static final String TAG = "MyBindService";
private final IBinder mBinder = new LocalBinder();
public MyBindService() {
Log.i(TAG, "MyBindService: ");
}
@Override
public void onCreate() {
Log.i(TAG, "onCreate: ");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind: ");
return mBinder;
}
@Override
public void onRebind(Intent intent) {
Log.i(TAG, "onRebind: ");
super.onRebind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind: ");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: ");
}
//必须继承binder,才能作为中间人对象返回
public class LocalBinder extends Binder{
public MyBindService getService() {
return MyBindService.this;
}
}
@Override
public void seeMovie() {
Log.i(TAG, "seeMovie: ");
}
@Override
public void listenMusic() {
Log.i(TAG, "listenMusic: ");
}
}
最后不要忘记服务需要在AndroidManifest.xml中注册