最近有個項目剛好使用了Service,特別是AIDL遠(yuǎn)程服務(wù),經(jīng)過這次項目對Service有了更好的理解,在這里作個總結(jié)。
創(chuàng)新互聯(lián)公司服務(wù)項目包括阜城網(wǎng)站建設(shè)、阜城網(wǎng)站制作、阜城網(wǎng)頁制作以及阜城網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,阜城網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到阜城省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
startService / bindService 混合使用
如果startService / bindService 混合使用 那Service的生命同期會怎樣呢,其實只要記住以上的思路,這種問題很好理解。首先 startService 與 stopService 對應(yīng) ,沒有stopService 之前不會 destroy Service , bindService 與 unbindService對應(yīng) ,沒有 unbindService 前也不會destroy Service。
為服務(wù)添加權(quán)限
相信大家做的服務(wù)都是公共的,即所有應(yīng)用都可以調(diào)用。但是如果我想我的服務(wù)只給特定的應(yīng)用調(diào)用,應(yīng)該如何設(shè)置呢?我們可以給服務(wù)添加權(quán)限。關(guān)于權(quán)限,Android系統(tǒng)給權(quán)限為了四個類別:
<uses-permission android:name="android.permission.custom.XXX"/>
如果我們想讓自己開發(fā)的Service只能被特定的Client調(diào)用,那就可以添加自定義的權(quán)限。比如危險級,我們可以在AndroidManifest.xml中聲明對應(yīng)的權(quán)限,只有應(yīng)用也設(shè)置了這個權(quán)限,才能正常啟動服務(wù)。
關(guān)于AIDL遠(yuǎn)程服務(wù)
所謂的AIDL遠(yuǎn)程服務(wù) 就是運行在另一個進程的服務(wù),平時我們調(diào)用的服務(wù)都運行在主線程。要使用AIDL服務(wù)就必須寫AIDL接口,向外暴露接口就可以與遠(yuǎn)程服務(wù)進行交互了。對于AIDL有如下幾個值得注意的地方:
AIDL的接口如何升級?
在做一個比較大型的項目,那項目會不斷迭代,那就有可能增加、修改AIDL接口,那如何保證AIDL接口和老的接口不會混亂呢,根據(jù)我的經(jīng)驗有如下總結(jié):
Service管理多個客戶端
如果Service有多個客戶端,如何安全地與它們通信呢?如何給各個客戶端回調(diào)結(jié)果呢? 在這里我要說說我在最近項目出現(xiàn)的一個問題,我在項目中要做一個公共的服務(wù),類似于指紋解鎖,其它應(yīng)用通過調(diào)用我的服務(wù)來獲取結(jié)果,我設(shè)計了start(callback), stop()兩個接口,一開始我就用單回調(diào)的方式,即在代碼中定義一個callback的屬性,誰調(diào)用了start就把callback設(shè)置成誰,只有最后一個調(diào)用start的Client能夠獲得回調(diào),代碼如下 :
private Callbak mCallback; public void start(Callback callback) { this.mCallback = callback; } public void stop() { this.mCallback = null; }
這種方式,在單個應(yīng)用時是很有效的,在多個應(yīng)用時,只要應(yīng)用能按順序執(zhí)行start、stop 那這個接口的設(shè)計也沒什么問題。但是事情沒想象中那么簡單,如果Client1調(diào)用了start,跟著Client2也調(diào)用了start,這時Client1 要stop,那會怎樣,那整個服務(wù)都stop了。這個就是我設(shè)計的服務(wù)中出現(xiàn)的大問題,之后我想著為我的服務(wù)接口作一些改變,以適應(yīng)這種多應(yīng)用的不按順序的調(diào)用 。我第一個想法就是用register、unregister的方式,用一個list收集所有的callback ,回調(diào)時可以輪循,stop時也可以通過判斷l(xiāng)ist的個數(shù),如果是小于等于1,那就執(zhí)行stop :
private List<Callbak> mCallbacks; public void start(Callback callback) { mCallbacks.add(callback); } public void stop(Callback callback) { mCallbacks.remove(callback); if(list.size() >= 1) return; }
考慮到接口的升級,這個改動是最小的,只給stop添加了一個參數(shù)。但是這個方式也有毛病,我們服務(wù)對Callback的引用是強引用,如果Client異常退出了,那引用還在并且會越積越多,在回調(diào)的時候,也可能出現(xiàn)DeadObjectException的錯誤。通過網(wǎng)絡(luò)查找資料,我找到了RemoteCallbackList,RemoteCallbackList也是一個列表,保存的是回調(diào)接口,使用Link-To-Death回調(diào) (在Sevice中接受到這個Binder對象,并且使用 binder.linkToDeath(),注冊一個DeathRecipient回調(diào);實現(xiàn)DeathRecipient。當(dāng)Client意外退出的時候,DeathRecipient.binderDied()將被回調(diào),我們可以在這里釋放相關(guān)的資源。)。最終代碼如下:
private RemoteCallbackList<Callback> mCallbacks = new RemoteCallbackList<>(); public void start(Callback callback) { mCallbacks.register(callback); } public void stop(Callback callback) { mCallbacks.unregister(callback); if(mCallbacks.getBroadcastItem() >= 1) return; } private void notifyResult(String result) { final int len = mCallbacks.beginBroadcast(); for (int i = 0; i < len; i++) { try { mCallbacks.getBroadcastItem(i).onResult(result); } catch (RemoteException e) { e.printStackTrace(); } } mCallbacks.finishBroadcast(); }
使用Messenger 實現(xiàn) Servie與Client端通信
Messenger是基于Handler的,通過為Messenger添加Handler來傳遞處理數(shù)據(jù),之后Service與Client的通信都是通過傳遞的Handler來進行。用這種方式可以不需要定義AIDL接口,也就不出現(xiàn)因為修改AIDl接口所造成的接口版本不對應(yīng)的麻煩。
Messenger的使用就是通過 Handler傳遞消息, 客戶端send方法發(fā)送的是一個Message,這個Message.replyTo指向的是一個Messenger,Messenger又持有客戶端的一個Binder對象(MessengerImpl),服務(wù)端正是利用這個Binder對象做的與客戶端的通信。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)站欄目:詳解AndroidService使用時的注意事項
本文來源:http://aaarwkj.com/article42/ihhjhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、響應(yīng)式網(wǎng)站、云服務(wù)器、網(wǎng)站策劃、移動網(wǎng)站建設(shè)、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)