最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Android Service 使用時的注意事項

 更新時間:2017年10月30日 08:27:57   作者:蘭蘭笑笑生  
這篇文章主要介紹了詳解Android Service 使用時的注意事項,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

最近有個項目剛好使用了Service,特別是AIDL遠(yuǎn)程服務(wù),經(jīng)過這次項目對Service有了更好的理解,在這里作個總結(jié)。

startService / bindService 混合使用

  1. 每一次調(diào)用 startService 都會回調(diào)onStartCommand,之后調(diào)用了stopService之后就會 destroy Service。即使有多個client啟動服務(wù),那調(diào)用一次stopService 就能 destroy Service 。通過這種方式還有一個好處就是Service可以通過調(diào)用 stopSelf 主動退出。
  2. 第一次調(diào)用bindService 的時候才會回調(diào) onBind,如果有多個client連接服務(wù),在最后一個client調(diào)用unbindService時才會回調(diào) onUnbind,并destroy Service。

如果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)限為了四個類別:

  1. 普通級: 這些權(quán)限并不能真正傷害到用戶(比如更換壁紙),當(dāng)程序需要這些權(quán)限是,開發(fā)者不需要指定程序會自動賦予這些權(quán)限。
  2. 危險級: 這些權(quán)限可能會帶來真的傷害(比如打電話,打開網(wǎng)絡(luò)鏈接等),如果要使用它們需要開發(fā)者在AndroidManifest.xml中聲明對應(yīng)的權(quán)限。
  3. 簽名級: 如果應(yīng)用使用的是相同的簽名證書時,這些權(quán)限會自動授予給聲明或者創(chuàng)建這些權(quán)限的程序。設(shè)計這一層級權(quán)限的目的是方便組件間數(shù)據(jù)共享。
  4. 簽名/系統(tǒng)級: 和簽名級一樣,例外的是系統(tǒng)鏡像是自動獲取這些權(quán)限的,這一層級是專為設(shè)備制造商設(shè)計的。
<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ù) 就是運行在另一個進(jìn)程的服務(wù),平時我們調(diào)用的服務(wù)都運行在主線程。要使用AIDL服務(wù)就必須寫AIDL接口,向外暴露接口就可以與遠(yuǎn)程服務(wù)進(jìn)行交互了。對于AIDL有如下幾個值得注意的地方:

  1. AIDL接口的函數(shù)都不支持重載,即函數(shù)名不能一樣,即使函數(shù)參數(shù)個數(shù)不一樣。
  2. AIDL接口傳遞的參數(shù)只有是基本數(shù)據(jù)類型、String 和CharSequence、List 和 Map、實現(xiàn)android.os.Parcelable 接口的類。
  3. 既然AIDL是在另一個進(jìn)程的服務(wù),那客戶端調(diào)用的AIDL接口是否堵塞? 答案是肯定的。如果不加 oneway 修飾符,那客戶端調(diào)用的接口都是堵塞的,但是oneway修飾符也有限制,就是oneway接口下面的方法都必須是返回void類型,不能返回其他類型的數(shù)據(jù)。

AIDL的接口如何升級?

在做一個比較大型的項目,那項目會不斷迭代,那就有可能增加、修改AIDL接口,那如何保證AIDL接口和老的接口不會混亂呢,根據(jù)我的經(jīng)驗有如下總結(jié):

  1. 對于增刪參數(shù)的接口:AIDL函數(shù)的訪問會檢測參數(shù),Client有參數(shù)的接口可以調(diào)用Service的接口(不管有無參數(shù)),反過來,Client的接口沒參數(shù)就只能調(diào)用Service沒有參數(shù)的接口。比如我們的新接口定義函數(shù)添加了參數(shù),那client必須同時或提前修改,不然我們發(fā)布了新接口的Service應(yīng)用,Client就不能調(diào)用了,但是Client用新接口是可以去訪問老接口的服務(wù)的。
  2. 對于增刪函數(shù)的接口:服務(wù)端增加函數(shù)并不影響客戶端,相反客戶端增加服務(wù)端沒有的接口就會訪問無效果,如果客戶端增加接口有返回值就返回默認(rèn)值。

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來進(jìn)行。用這種方式可以不需要定義AIDL接口,也就不出現(xiàn)因為修改AIDl接口所造成的接口版本不對應(yīng)的麻煩。

Messenger的使用就是通過 Handler傳遞消息, 客戶端send方法發(fā)送的是一個Message,這個Message.replyTo指向的是一個Messenger,Messenger又持有客戶端的一個Binder對象(MessengerImpl),服務(wù)端正是利用這個Binder對象做的與客戶端的通信。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • kotlin使用Dagger2的過程全紀(jì)錄

    kotlin使用Dagger2的過程全紀(jì)錄

    Dagger2是一款基于Java注解,在編譯階段完成依賴注入的開源庫,主要用于模塊間解耦,方便進(jìn)行測試。下面這篇文章主要給大家介紹了關(guān)于kotlin使用Dagger2的過程的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Android如何快速適配暗黑模式詳解

    Android如何快速適配暗黑模式詳解

    微信在前段時間的更新中也實現(xiàn)了暗黑模式,而蘋果系統(tǒng)也早就支持暗黑模式,Android也一樣可以實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Android如何快速適配暗黑模式的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 如何將Android?Studio卸載干凈

    如何將Android?Studio卸載干凈

    這篇文章主要介紹了如何將Android?Studio卸載干凈,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Android中使用 AutoCompleteTextView 實現(xiàn)手機號格式化附帶清空歷史的操作

    Android中使用 AutoCompleteTextView 實現(xiàn)手機號格式化附帶清空歷史的操作

    有個小伙伴遇到了這樣一個問題,就是AutoCompleteTextView實現(xiàn)自動填充的功能。同時要具備手機格式化的功能。接下來通過本文給大家分享使用 AutoCompleteTextView 實現(xiàn)手機號格式化附帶清空歷史的操作方法,需要的朋友參考下
    2017-03-03
  • Android studio六大基本布局詳解

    Android studio六大基本布局詳解

    這篇文章主要介紹了Android常用的布局方式:線性布局,相對布局,表格布局,層布局,絕對布局,網(wǎng)格布局,用的相對較多的是線性布局和相對布局。感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • Android中實現(xiàn)下載URL地址的網(wǎng)絡(luò)資源的實例分享

    Android中實現(xiàn)下載URL地址的網(wǎng)絡(luò)資源的實例分享

    這篇文章主要介紹了Android中實現(xiàn)下載URL地址的網(wǎng)絡(luò)資源的實例,其中還有一個進(jìn)行多線程下載的Java代碼示例,非常典型,需要的朋友可以參考下
    2016-04-04
  • 保存ListView上次的滾動條的位置實例(必看)

    保存ListView上次的滾動條的位置實例(必看)

    下面小編就為大家?guī)硪黄4鍸istView上次的滾動條的位置實例(必看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Android使用vitamio插件實現(xiàn)視頻播放器

    Android使用vitamio插件實現(xiàn)視頻播放器

    這篇文章主要為大家詳細(xì)介紹了Android使用vitamio實現(xiàn)視頻播放器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法

    Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法

    這篇文章主要介紹了Android中檢查、監(jiān)聽電量和充電狀態(tài)的方法,如判斷當(dāng)前充電狀態(tài)、監(jiān)聽充電狀態(tài)的改變、判斷當(dāng)前剩余電量等,需要的朋友可以參考下
    2014-06-06
  • Android自定義ImageView實現(xiàn)在圖片上添加圖層效果

    Android自定義ImageView實現(xiàn)在圖片上添加圖層效果

    這篇文章給大家主要介紹了利用Android自定義ImageView如何實現(xiàn)在圖片上添加圖層的效果,實現(xiàn)的效果類似在圖片增加秒殺、搶光等標(biāo)簽圖片,對大家開發(fā)的時候具有一定的參考借鑒價值,有需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11

最新評論

手游| 高台县| 兴山县| 永嘉县| 岳西县| 绩溪县| 泸定县| 新泰市| 保康县| 武夷山市| 苏尼特右旗| 安图县| 昌黎县| 鲁山县| 彰化市| 辉南县| 石台县| 奉贤区| 隆安县| 渭源县| 恭城| 绿春县| 高台县| 来宾市| 石林| 皋兰县| 美姑县| 扎赉特旗| 霍邱县| 龙里县| 炎陵县| 砀山县| 邯郸县| 永嘉县| 仁化县| 图们市| 个旧市| 射洪县| 麦盖提县| 罗平县| 鄂尔多斯市|