Android Activity与Service的通信方式

概要

本文主要讲解Service与Activity进行通信的几种方式,Activity主要通过Intent出传递数据到Service,而比较常见的Service传递数据到Activity有三种方式,但是这次所介绍的Service与Activity的通信方式都是位于同一应用进程中的,并没有介绍不同进程之间如何通信,不同进程通过aidl或者Messenger在以后的文章中会再做详细的介绍。

Service和Activity是Android中最常用的两大组件,Activity的设计与Web页面非常类似,从页面的跳转通过连接,以及从页面的定位通过URL,从每个页面的独立封装等方面都可以看出来,它主要负责与用户进行交互。Service则是在后台运行,默默地为用户提供功能,进行调度和统筹,它用来“执行”后台的、耗时的、重要的任务,三者缺一不可,而最重要的原因是第三点:要执行重要的任务。

从上面可以看出,Activity负责与用户的直接交互,Service是运行在后台用户不可见的而且常常执行的是重要的任务,既然是重要的任务然而用户却不知道任务的执行情况,比如下载,用户想知道下载的进度,这种情况下就需要与Activity通信,方面用户实时知道任务的执行情况。

Activity传递数据到Service

这种方式传递数据基本上是依赖Intent来传递数据的,更为详细的请参考Intent学习笔记,在Activity中可以使用两种方式来与Service进行交互,一种是通过bindService(Intent service, ServiceConnection conn, int flags)方法,另一种是startService(Intent service),当然了也可以通过广播来与服务通信,但是个人感觉Activity通过Broadcast来通信就有点多此一举了,但是反过来则是可行的,在Service中通过Broadcast来传递数据到Activity。

接下来介绍最常见的通过Service传递数据到Activity的三种方式。

方式一:通过Binder

在以前的一篇文章Service简介及启动方式就已经介绍过,Service主要提供两种功能,其中之一就是将应用程序的某些功能暴露给其它程序,该种方式就是通过Binder来实现的。

我们知道在每创建一个Service实例是都要实现一个方法onBind(Intent intent),该方法返回一个IBinder类型的实例,IBinder是远程对象的基本接口,是为高性能而设计的轻量级远程调用机制的核心部分。但它不仅用于远程调用,也用于进程内调用。这个接口定义了与远程对象交互的协议。不要直接实现这个接口,而应该从Binder派生。

下面是一个简单的Service实现:

 

 

当我们在Activity通过bindService(Intent service, ServiceConnection conn, int flags)来绑定一个Service时,bindService会立即返回,它不会返回Ibinder给客户端,要接收Ibinder,客户端Activity必须创建一个长连接ServiceConnection的实例并传给bindService(),ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder。

下面是Activity的代码:

 

 

在本实例中,主要是通过IBinder来建立一个Service与Activity的一个桥梁,通过Binder对象来调用Service中的方法,当然了也可以在Service中在新建一个Binder对象时将Service对象本身作为一个方法的返回值返回,然后我们在Activity中就可以直接通过ServiceConnection长连接回调函数中的IBinder对象来得到一个Service实例,这样就可以使用Service中暴露的特定方法了,这种方式好像更简洁了,IBinder的目的就是为了将Service对象传递到Activity,其余的事情都不用管了。

方式二:通过Broadcast广播

在上一篇文章中我们已经讲过Broadcast可以用于应用程序之间的通信,更多的内容可以查看Android Broadcast广播机制

Service的代码实现:

 

 

Activity中代码实现:

 

 

方式三:自定义接口回调

事实上方式一也是一种接口回调,只是回调接口中传递的是IBinder的一个实例而已,这里我们们仍然会借助第一种方式的接口回调来获取IBinder的一个实例,然后通过该实例获取相对应得Service实例,再通过Service中自定义的回调接口将下载的进度实时更新。先看一下回调接口的定义:

 

 

Service代码:

 

 

Activity的部分代码:

 

 

小结

本篇文章虽然说是三种方式实现Service传递数据到Activity,可是归根到底仍然只是一种方式,都是借助于IBinder暴露Service中的相应操作。网上还有些文章中提到用观察者模式,观察者模式也是接口回调的一种方式,xUtils框架中的下载直接使用Service中的静态方法来获取了下载管理器DownloadManager,它的这种方式是直接在Activity或者Fragment中使用了DownloadService,然后在获取下载管理器DownloadManager的方法中再启动Service,简单来说就是调用一个类的静态方法,这种方式跟面向对象中在一个类中调用另一个类的静态方法一样,不需要借助任何纽带桥梁直接创建调用,应用程序之间通信,大概就这么两种形式,一种是通过一个桥梁纽带来传递数据,另外一种就是直接在调用者中使用被调用者。

本文地址:www.sunnyang.com/357.html

posted @ 2017-03-13 12:30  天涯海角路  阅读(6805)  评论(0编辑  收藏  举报