中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中 AIDL如何使用

發布時間:2021-06-23 14:33:28 來源:億速云 閱讀:154 作者:Leah 欄目:互聯網科技

Android中 AIDL如何使用,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Android AIDL的用法

一、什么是AIDL服務

   一般創建的服務并不能被其他的應用程序訪問。為了使其他的應用程序也可以訪問本應用程序提供的服務,Android系統采用了遠程過程調用(Remote Procedure Call,RPC)方式來實現。與很多其他的基于RPC的解決方案一樣,Android使用一種接口定義語言(Interface Definition Language,IDL)來公開服務的接口。因此,可以將這種可以跨進程訪問的服務稱為AIDL(Android Interface Definition Language)服務。 

二、AIDL基本語法 

  AIDL使用簡單的語法來聲明接口,描述其方法以及方法的參數和返回值。這些參數和返回值可以是任何類型,甚至是其他AIDL生成的接口。
  其中對于Java編程語言的基本數據類型 (int, long, char, boolean,String,CharSequence)集合接口類型List和Map,不需要import 語句。
  而如果需要在AIDL中使用其他AIDL接口類型,需要import,即使是在相同包結構下。AIDL允許傳遞實現Parcelable接口的類,需要import
  需要特別注意的是,對于非基本數據類型,也不是String和CharSequence類型的,需要有方向指示,包括in、out和inout,in表示由客戶端設置,out表示由服務端設置,inout是兩者均可設置。

  AIDL只支持接口方法,不能公開static變量。 

三、android應用層使用AIDL

3.1、簡要步驟

  1、在Eclipse Android工程的Java包目錄中建立一個擴展名為A.aidl的文件,并寫下需要的接口。如果aidl文件的內容是正確的,ADT會在gen目錄下自動生成一個A.Java接口文件。
  2、建立一個服務類(Service的子類)。并在創建的服務類中創建一個內部類,實現由aidl文件生成的Java接口。
  3、在服務類的onBind方法返回時,將實現aidl接口的內部類對象返回出去。
  4、在AndroidManifest.xml文件中配置AIDL服務,尤其要注意的是,<action>標簽中android:name的屬性值就是客戶端要引用該服務的ID,也就是Intent類的參數值。

3.2、具體操作

3.2.1、創建文件IMyService.aidl: 

        Android中 AIDL如何使用
  文件內容:

  1. package du.pack;  

  2. interface IMyService{  

  3.     //只有一個接口  

  4.     String getValue();  

  5. }   

3.2.2、創建服務類及實現內部類

  1. public class MyService extends Service {  

  2.   

  3.     @Override  

  4.     public IBinder onBind(Intent arg0) {  

  5.         // 把內部類的對象返回給客戶端使用  

  6.         return new MyServiceImpl();  

  7.     }  

  8.   

  9.     // 創建一個繼承自IMyService.Stub的內部類  

  10.     public class MyServiceImpl extends IMyService.Stub {  

  11.   

  12.         // 必須實現AIDL文件中的接口  

  13.         public String getValue() throws RemoteException {  

  14.             return null;  

  15.         }  

  16.     }  

  17. }  

  注意,我們寫的service中,onBind方法必須返回MyServiceImpl類的對象實例,否則客戶端無法獲得服務對象。

3.2.3、在AndroidManifest.xml文件中配置MyService類

  1. <service android:name=".MyService" >  

  2.     <intent-filter>  

  3.         <action android:name="du.pack.IMyService" />  

  4.     </intent-filter>  

  5. </service>  

  上面的"du.pack.IMyService"是客戶端用于訪問AIDL服務的ID。 

4、本地客戶端的使用方法 

    4.1、新建一個Eclipse Android工程,并將剛才遠程服務端自動生成的gen目錄下面的IMyService.java文件連同包目錄一起復制到客戶端工程的src目錄中。

        
 

 4.2、調用AIDL服務首先要綁定服務,然后才能獲得服務對象。

  1. public class AidlClientTestActivity extends Activity {  

  2.     // 遠程服務端的對象  

  3.     IMyService mIMyService;  

  4.     private ServiceConnection mConnection = new ServiceConnection() {  

  5.   

  6.         public void onServiceConnected(ComponentName name, IBinder service) {  

  7.             // 綁定成功,得到遠程服務端的對象,目標完成!!!  

  8.             mIMyService = IMyService.Stub.asInterface(service);  

  9.         }  

  10.   

  11.         public void onServiceDisconnected(ComponentName name) {  

  12.             // 解除綁定  

  13.             mIMyService = null;  

  14.         }  

  15.   

  16.     };  

  17.   

  18.     @Override  

  19.     public void onCreate(Bundle savedInstanceState) {  

  20.         super.onCreate(savedInstanceState);  

  21.         setContentView(R.layout.main);  

  22.   

  23.         // 綁定遠程服務端服務  

  24.         Intent serviceIntent = new Intent("du.pack.IMyService");  

  25.         bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);  

  26.     }  

  27. }  

5、用法小結 

  回顧一下整個調用的過程:
  服務端方面:將需要開放的接口抽象到aidl文件中,然后在自己的內部類中對接口進行實現,并在自己被綁定的時候把內部類對象返回給客戶端。客戶端方面:當我們需要遠程某個Service時,就像在綁定本地的Service一樣去bindService,然后在綁定成功的回調函數中(也就是onServiceConnected方法)得到一個Ibinder對象(比如Service),這時調用IMyService.Stub.asInterface(service)這樣的語句,就可以得到服務端開放的interface接口對象,此時客戶端可以直接調用這個對象的方法,猶如直接調用遠程的Service對象一般。

四、Framework中使用AIDL

         Framework中使用AIDL我們通過ITelephonyRegistry這個SystemService進行分析。該服務的主要作用就是對通話相關的事件進行監聽,我們重心放在AIDL的實現結構上,不去關注ITelephonyRegistry具體的實現。

1、AIDL文件相關

        先來看一下這個服務的AIDL文件: 

  1. @ITelephonyRegistry.aidl  

  2. interface ITelephonyRegistry {  

  3.     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);  

  4.     void notifyCallState(int state, String incomingNumber);  

  5.     void notifyServiceState(in ServiceState state);  

  6.     void notifySignalStrength(in SignalStrength signalStrength);  

  7.     void notifyMessageWaitingChanged(boolean mwi);  

  8. }  

        再來看這個服務的真正實現: 

  1. @TelephonyRegistry.java  

  2. class TelephonyRegistry extends ITelephonyRegistry.Stub {  

  3.     TelephonyRegistry(Context context) {  

  4.         ......  

  5.     }  

  6.     void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow){  

  7.         ......  

  8.     }  

  9.     void notifyCallState(int state, String incomingNumber){  

  10.         ......  

  11.     }  

  12.     void notifyServiceState(in ServiceState state){  

  13.         ......  

  14.     }  

  15.     void notifySignalStrength(in SignalStrength signalStrength){  

  16.         ......  

  17.     }  

  18.     void notifyMessageWaitingChanged(boolean mwi){  

  19.         ......  

  20.     }  

  21. }  

        上面的兩個文件是這個服務的核心部分,aidl文件規定了這個服務的功能,而java文件是對功能的具體實現。但是,此時的TelephonyRegistry并沒有繼承Service的類,也就是說,當前他并不具備作為一個Service的資格。那么他是如何變成一個服務的呢?

     2、服務的注冊過程

         在SystemService中可以找到答案。

  1. @SystemServer.java  

  2. class ServerThread extends Thread {  

  3.     @Override  

  4.     public void run() {  

  5.         try {  

  6.             telephonyRegistry = new TelephonyRegistry(context);  

  7.             ServiceManager.addService("telephony.registry", telephonyRegistry);  

  8.         }  

  9.     }  

  10. }  

        我們看到,在這一步中,把telephonyRegistry對象(也就是ITelephonyRegistry.Stub的子類對象)作為一個Service注冊給了ServiceManager。并且注冊的名字是“telephony.registry”
        有了這一步,TelephonyRegistry就可以作為服務提供者向客戶端開放了。也就是說,有了這一步,TelephonyRegistry才算上是一個真正的Service,可以接受客戶端的連接申請。

        那么接下來,我們怎么得到這個Service呢?

3、如何得到注冊的服務

        既然通過ServiceManager注冊了服務,我們就需要再次通過ServiceManager得到它的服務對象。

  1. private ITelephonyRegistry sRegistry;  

  2. sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));  

        通過這樣的方法,我們就得到了ITelephonyRegistry.aidl的對象sRegistry。

關于Android中 AIDL如何使用問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚顺市| 关岭| 肥城市| 新乡市| 吉林市| 宿松县| 张家口市| 蒙自县| 石泉县| 宣武区| 民县| 合川市| 阿瓦提县| 黔江区| 始兴县| 昌吉市| 二连浩特市| 革吉县| 华池县| 共和县| 类乌齐县| 天水市| 常熟市| 兰考县| 朝阳市| 汾阳市| 阿勒泰市| 遂宁市| 北安市| 西贡区| 茶陵县| 宁波市| 独山县| 卢氏县| 亚东县| 金华市| 岳阳县| 会东县| 肃南| 宁乡县| 咸阳市|