在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