Android中startService和bindService的区别

Service属于android四大组件之一,在很多地方经常被用到。开启Service有两种不同的方式:startService和bindService。不同的开启方式,Service执行的生命周期方法也不同。
首先,先看一下Service都有哪些生命周期方法。
要想使用Service需要写一个自己的MyService类,并继承Service。还要在清单文件中声明一下。

<service android:name=".MyService"/>
public class MyService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("call", "onBind");
        return null;
    }

    @Override
    public void onCreate() {
        Log.e("call", "onCreate");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("call", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e("call", "onDestroy");
        super.onDestroy();
    }
}

startService开启服务和结束服务稍微简单一点。

//开启服务
Intent service = new Intent(this, MyService.class);
startService(service);
//结束服务
stopService(service);

开启服务时,调用一次startService,生命周期执行的方法依次是:
onCreate() ==> onStartCommand();
调用多次startService,onCreate只有第一次会被执行,而onStartCommand会执行多次。
结束服务时,调用stopService,生命周期执行onDestroy方法,并且多次调用stopService时,onDestroy只有第一次会被执行。

bindService开启服务就多了一些内容。

//开启服务
Intent service = new Intent(this, MyService.class);
MyConnection conn = new MyConnection();
//第一个参数:Intent意图
//第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null
//第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建service
bindService(service, conn, BIND_AUTO_CREATE);

bindService的方法参数需要一个ServiceConnection接口的实现类对象,我们自己写一个MyConnection类,并实现里面的方法。

private class MyConnection implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //只有当我们自己写的MyService的onBind方法返回值不为null时,才会被调用
            Log.e("call","onServiceConnected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //这个方法只有出现异常时才会调用,服务器正常退出不会调用。
            Log.e("call","onServiceDisconnected");
        }
    }
//结束服务
unbindService(conn);

bingService开启服务时,根据生命周期里onBind方法的返回值是否为空,有两种情况。
1、onBind返回值是null;
调用bindService开启服务,生命周期执行的方法依次是:
onCreate() ==> onBind();
调用多次bindService,onCreate和onBind也只在第一次会被执行。
调用unbindService结束服务,生命周期执行onDestroy方法,并且unbindService方法只能调用一次,多次调用应用会抛出异常。使用时也要注意调用unbindService一定要确保服务已经开启,否则应用会抛出异常。
2、onBind返回值不为null;
看一下android对于onBind方法的返回类型IBinder的介绍,字面上理解是IBinder是android提供的进程间和跨进程调用机制的接口。而且返回的对象不要直接实现这个接口,应该继承Binder这个类。
那么我们就在自己写的MyService里创建一个内部类MyBinder,让他继承Binder,并在onBind方法里返回MyBinder的对象。

@Override
public IBinder onBind(Intent intent) {
    Log.e("call", "onBind");
    MyBinder mbind = new MyBinder();
    Log.e("call", mbind.toString());
    return mbind;
}
private class MyBinder extends Binder{
    public void systemOut(){
        System.out.println("该方法在MyService的内部类MyBinder中");
    }
}

这时候调用bindService开启服务,生命周期执行的方法依次是:
onCreate() ==> onBind() ==> onServiceConnected();
可以发现我们自己写的MyConnection类里的onServiceConnected方法被调用了。调用多次bindService,onCreate和onBind都只在第一次会被执行,onServiceConnected会执行多次。
并且我们注意到onServiceConnected方法的第二个参数也是IBinder类型的,不难猜测onBind()方法返回的对象被传递到了这里。打印一下两个对象的地址可以证明猜测是正确的。
也就是说我们可以在onServiceConnected方法里拿到了MyService服务的内部类MyBinder的对象,通过这个内部类对象,只要强转一下,我们可以调用这个内部类的非私有成员对象和方法。
调用unbindService结束服务和上面相同,unbindService只能调用一次,onDestroy也只执行一次,多次调用会抛出异常。
接下来我们说一下startService和bindService开启服务时,他们与activity之间的关系。
1、startService开启服务以后,与activity就没有关联,不受影响,独立运行。
2、bindService开启服务以后,与activity存在关联,退出activity时必须调用unbindService方法,否则会报ServiceConnection泄漏的错误。

最后还有一点,同一个服务可以用两种方式一同开启,没有先后顺序的要求,MyService的onCreate只会执行一次。
关闭服务需要stopService和unbindService都被调用,也没有先后顺序的影响,MyService的onDestroy也只执行一次。但是如果只用一种方式关闭服务,不论是哪种关闭方式,onDestroy都不会被执行,服务也不会被关闭。这一点需要注意。

推荐阅读更多精彩内容

  • 版权声明:本文为博主原创文章,未经博主允许不得转载 PS:转载请注明出处作者: TigerChain地址: htt...
    TigerChain阅读 374评论 0 3
  • Jianwei's blog 首页 分类 关于 归档 标签 巧用Android多进程,微信,微博等主流App都在用...
    justCode_阅读 3,719评论 1 21
  • 参考: 服务|Android Developers 一. 什么是服务 服务是一个可以在后台执行长时间运行操作而不提...
    NickelFox阅读 231评论 0 3
  • 我记得那个日子,五月三十日。 那是我兼职的第一天,公司说,让我一周来三到五天,具体几天,看事情的多少。其实我是希望...
    馒头爱豆包阅读 62评论 0 0
  • 一对父母,孩子们都大了,自己想做年轻时没做过的,回到乡下,种花种菜,养鸡养鸭,起初,孩子们不同意,说生活终于安定了...
    花花草草的字阅读 168评论 0 0