Android startservice & bindservice的区别

Android startservice & bindservice的区别

作为一个android开发者,service大家应该已经接触过了,接触Android的第一节课,就是将Android的四大组件,那么作为四大组件之一的service,你是否足够了解呢?

  1. service和thread的区别你是否知道?service真的能执行长时间的后台操作么?

  2. 你是否知道startservice和bindservice的区别呢?

  3. service的生命周期,我们是否应该主动结束一个service呢?service是否会导致内存泄露呢?

  4. service与intentservice的区别是什么?

上边是关于service的一些问题,问题1,我们已经在之前的博客上讲解过,详细内容见博客http://blog.csdn.net/u014088294/article/details/49907385

关于问题4,也可以参考我们之前的文章 ,http://blog.csdn.net/u014088294/article/details/44279399

我们主要解答问题2,startservice与bindservice的区别。

Developer上提到,service主要有两种形式,

  1. started
  2. bound

上边的started呢,对应与startservice,bound对应于bindservice,他们都是启动service的方式。

startservice

我们可以通过startservice来启动一个service,启动后,service在后台运行。通常来说,该service是无法返回结果的(这也是与bindservice的区别之一),比如我们可以下载一个文件。
和startservice对应的是stopservice,我们可以来显式的结束一个service。
service的生命周期也比较简单,和startservice相关的有三个函数,分别是onCreate,onStartCommand,onDestory。

当我们首次startserivce启动一个service的时候,会调用service的onCreate函数,创建该服务,然后调用onStartCommand函数,执行操作。如果我们多次通过startservice启动服务,那么onCreate只会调用一次,直接调用onStartCommand
我们可以调用stopsevice来结束一个service。同样,我们也可以多次调用(第一次调用已经结束,但是后来继续调用并不会产生异常)。

当一个service通过startservice启动后,它就独立于调用者而运行(也就是说,调用者的生命周期和它的生命周期没有关系),因此呢,service应该在任务完成的时候调用stopSelf函数或者调用者stopservice来结束该服务

Developer上提到,当我们的service执行完的时候,为了避免消耗系统资源或电量,应该结束该service。否则,该服务将会一直运行在后台,直到设备内存不足等原因把他关闭掉。

然而,startservice并不能解决我们所有的需求,比如,我有时候,需要service的返回结果,我需要和service交互,startservice显然不能完成。那么我们可以使用到bindservice

bindservice

Developer这样提到,

A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC).

我们可以利用bindservice来和service绑定,绑定后,我们可以和service交互,发送请求,得到结果甚至执行IPC通信。

那么,我们应该如何使用bindservice呢?

  1. 首先我们需要重载service的onBinder,返回一个IBinder对象。该对象是
    调用者和serivce交互的接口。
  2. 新建一个ServiceConnection变量,该类是监听Service是否bound的接口,我们重载其onServiceConnected和onServiceDisconnected方法。onServiceConnected方法中,我们得到了Service中onBinder返回的IBinder接口。
  3. 调用bindservice来绑定服务。

按照上边的步骤,我们的代码如下,
1. 重载onBinder并返回一个IBinder对象。在LocalBinder中,提供getSercive方法,返回service实例。

    public class LocalBinder extends Binder {
        MyService getService() {
            return MyService.this;
        }
    }

    private final IBinder mBinder = new LocalBinder();

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return mBinder;
    }

2.调用者中新建ServiceConnection接口,在onServiceConnected方法中,将IBinder对象转为LocalBinder对象,并调用其getService方法,得到Service。

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((MyService.LocalBinder) service).getService();
        }

        public void onServiceDisconnected(ComponentName className) {
              mBoundService = null;
        }
    };

3.调用者执行bindservice,其中mConnection为ServiceConnection接口。

bindService(new Intent(MainActivity.this,MyService.class), mConnection, Context.BIND_AUTO_CREATE);

当用户执行bindservice后,bind的结果会回调mConnection接口,若bind成功,就会回调onServiceConnected方法,然后我们在此方法中,得到了Service实例,得到Service实例后,然后我们就可以和Service交互了

我们继续完善代码,在Service的onCreate方法中,我们新建一个线程,每隔1s,计数器加1.其中count为成员变量,表示当前计数值,threadDisable表示是否service关闭。

        new Thread(new Runnable() {
            // @Override
            public void run() {
                while (!threadDisable) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    count++;
                    System.out.println("CountService Count is " + count);
                }
            }
        }).start();

然后,我们在Service中新建一个方法,返回计数值。

    public int getCount() {
        return count;
    }

那么我们在调用者中,就可以利用上边得到的mBoundService来调用getCount方法,达到与service交互的目的。
项目地址,https://github.com/KingPaul/ServiceDemo

你可能感兴趣的:(Android)