在android中,activity主要负责前台页面的展示,service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到activity与service之间的通信,我们一般在activity中启动后台service,通过intent来启动,intent中我们可以传递数据给service,而当我们service执行某些操作之后想要更新ui线程,我们应该怎么做呢?接下来我就介绍两种方式来实现service与activity之间的通信问题
通过binder对象
当activity通过调用bindservice(intent service, serviceconnection conn,int
flags),我们可以得到一个service的一个对象实例,然后我们就可以访问service中的方法,我们还是通过一个例子来理解一下吧,一个模拟下载的小例子,带大家理解一下通过binder通信的方式
首先我们新建一个工程communication,然后新建一个service类
上面的代码比较简单,注释也比较详细,最基本的service的应用了,相信你看得懂的,我们调用startdownload()方法来模拟下载任务,然后每秒更新一次进度,但这是在后台进行中,我们是看不到的,所以有时候我们需要他能在前台显示下载的进度问题,所以我们接下来就用到activity了
通过上面的代码我们就在activity绑定了一个service,上面需要一个serviceconnection对象,它是一个接口,我们这里使用了匿名内部类
在onserviceconnected(componentname name, ibinder service)
回调方法中,返回了一个msgservice中的binder对象,我们可以通过getservice()方法来得到一个msgservice对象,然后可以调用msgservice中的一些方法,activity的代码如下
其实上面的代码我还是有点疑问,就是监听进度变化的那个方法我是直接在线程中更新ui的,不是说不能在其他线程更新ui操作吗,可能是progressbar比较特殊吧,我也没去研究它的源码,知道的朋友可以告诉我一声,谢谢!
上面的代码就完成了在service更新ui的操作,可是你发现了没有,我们每次都要主动调用getprogress()来获取进度值,然后隔一秒在调用一次getprogress()方法,你会不会觉得很被动呢?可不可以有一种方法当service中进度发生变化主动通知activity,答案是肯定的,我们可以利用回调接口实现service的主动通知,不理解回调方法的可以看看
新建一个回调接口
msgservice的代码有一些小小的改变,为了方便大家看懂,我还是将所有代码贴出来
activity中的代码如下
用回调接口是不是更加的方便呢,当进度发生变化的时候service主动通知activity,activity就可以更新ui操作了
通过(广播)的形式
当我们的进度发生变化的时候我们发送一条广播,然后在activity的注册广播接收器,接收到广播之后更新progressbar,代码如下
总结:
activity调用bindservice (intent service, serviceconnection conn, int
flags)方法,得到service对象的一个引用,这样activity可以直接调用到service中的方法,如果要主动通知activity,我们可以利用回调方法
service向activity发送消息,可以使用广播,当然activity要注册相应的接收器。比如service要向多个activity发送同样的消息的话,用这种方法就更好
转载自:http://blog.csdn.net/xiaanming/article/details/9750689