AIDL在android系統中的作用

來源:互聯網
上載者:User

標籤:android   源碼   frameworks   aidl   

</pre><p>        <span style="font-size:12px;">AIDL是<span style="color: rgb(51, 51, 51); font-family: arial; font-size: 12.727272033691406px; line-height: 18.18181800842285px;"> Android Interface definition language的縮寫,一看就明白,它是一種android內部進程通訊介面的描述語言,通過它我們可以定義進程間的通訊介面。最近看了下AIDL在Android系統中的用法,在網上看到很多初學的朋友不太明白AIDL的實際作用,android提供了很多處理序間通訊的組件,像action、broadcast、contentprovide都可以實現進程間的通訊,為什麼還要用AIDL這個東西呢?我在android源碼中實現了一個自己寫的AIDL例子,用以簡單解釋下AIDL的作用。</span></span></p><p><span style="font-size:12px;"><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 12.727272033691406px; line-height: 18.18181800842285px;">     有開發過藍芽或者WIFI應用的朋友肯定都知道,要去操作它必須先獲得一個管理類,比如WIFI的管理類是WifiManager,通過getSystemService(Context.WIFI_SERVICE)就可以得到wifi的系統管理權限,這個<span style="color: rgb(51, 51, 51); font-family: arial; font-size: 13px; line-height: 18.171875px;">WifiManager提供了很多的方法可以讓使用者去操作它,比如開啟wifi可以調用setWifiEnabled(true)方法。那這個Manager到底做了什麼工作呢?是怎樣實現開啟wifi的呢?其實這個Manager只是一個管理類,真正幹活的另有其人,是一個叫WifiService的系統服務。在Android系統中有很多的Manager,wifi的管理類叫WifiManager,藍芽的管理類叫BluetoothManager,只要有xxxManager.java,就會有Ixxx.aidl,並且有xxxService.java。這個aidl類就是實現Manager和Service通訊的橋樑。</span></span></span></p><p><span style="font-size:12px;"><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 12.727272033691406px; line-height: 18.18181800842285px;"><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 13px; line-height: 18.171875px;">     下面看我加的一個例子:</span></span></span></p><p><span style="font-size:12px;"><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 12.727272033691406px; line-height: 18.18181800842285px;"><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 13px; line-height: 18.171875px;">      首先在android源碼中的frameworks/base/</span></span></span><span style="color: rgb(51, 51, 51); font-family: arial; font-size: 12.727272033691406px; line-height: 18.18181800842285px;">core/java/android/os/目錄下加入一個IMyTestService.aidl,一般系統的AIDL檔案都放在這個目錄下。</span></p><p><span style="font-size: 12px; color: rgb(51, 51, 51);"><span style="line-height: 18.171875px;"></span></span><pre name="code" class="java" style="font-family: arial;">package android.os;/** {@hide} */interface IMyTestService{    void open();    void close();}
關於AIDL的語言規範我就不多說了,其實和Java寫介面差不多(它本來就是一種介面語言)。裡面只定義兩個簡單的方法,open和close。
然後在frameworks/base/Android.mk中添加一句:core/java/android/os/IMyTestService.aidl。android系統的編譯目標是通過Android.mk來指定的,在這裡加上自訂的aidl檔案系統才會把這個檔案編譯進去,最終產生一個叫IMyTestService.java的檔案。這一部分用eclipse可以很直觀的看到,在項目添加了aidl檔案後eclipse會自動編譯此aidl,產生的檔案存放在gen目錄下。

AIDL添加好了後,在frameworks/base/services/java/com/android/server/目錄下添加一個MyTestService.java,繼承IMytestService這個aidl。
package com.android.server;import android.net.wifi.WifiManager;import android.content.Context;import android.os.IMyTestService;import android.util.Log;public class MyTestService extends IMyTestService.Stub {    private static final String TAG = "MyTestService";    private Context mContext;    private WifiManager mWifiManager;    public MyTestService(Context context/*,WindowManagerService wm*/) {        super();        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);    }    /* close wifi */    public void close() {        mWifiManager.setWifiEnabled(false);    }    /* open wifi */    public void open() {        mWifiManager.setWifiEnabled(true);    }}
實現aidl檔案中定義的open和close方法,我這裡很簡單,open就是去開啟wifi,close就去關閉wifi。
然後在frameworks/base/core/java/android/content/Context.java檔案中加入一個靜態字串:public static final String MY_TEST_SERVICE = "my_test_service";
最後把這個服務添加到系統服務中去,在frameworks/base/services/java/com/android/server/SystemServer.java中Thread的run方法中添加下面代碼:
            try {                 Slog.i(TAG, "My Test Service");                 myService = new MyTestService(context);                 ServiceManager.addService(Context.MY_TEST_SERVICE, myService);             } catch (Throwable e) {                 reportWtf("starting my test Service", e);             }
<pre name="code" class="java" style="color: rgb(51, 51, 51); line-height: 18.171875px;"><span style="font-family:arial;">myService需要在前面聲明一下。SystemService是android系統跑起來之後就會調用的,這裡的意思是把MyTestService添加到系統服務中去,並取名字叫</span><pre name="code" class="java" style="font-family: arial; color: rgb(51, 51, 51); line-height: 18.171875px;">Context.MY_TEST_SERVICE,也就是<span style="font-family: arial;">my_test_service。這樣看起來是不是很熟悉呢?每個開發人員在開發過程中肯定會調用系統服務的,比如電源管理服務:getSystemService(Context.POWER_SERVICE),這個Service也是在這裡添加進去的。android有很多的系統服務,這裡就不一一例舉了,有興趣的朋友可以自行看看這個檔案。</span>
<span style="font-family: arial;"></span>
<span style="font-family: arial;">現在aidl添加了,service也添加了,並且添加進了系統服務,那麼還少一個Manager,可以讓第三方程式調用的Manager。</span>
<span style="font-family: arial;">在frameworks/base/core/java/android/device/目錄下添加MyTestManager.java檔案:</span>
<span style="font-family: arial;">package android.device;import android.util.Log;import android.content.Context;import android.os.RemoteException;import android.os.IMyTestService;import android.os.ServiceManager;public class MyTestManager {<span style="white-space:pre"></span>private static final String TAG = "MyTestManager";<span style="white-space:pre"></span>private IMyTestService mTestService;<span style="white-space:pre"></span>public MyTestManager() {<span style="white-space:pre"></span><span style="white-space:pre"></span>    IMyTestService mService = IMyTestService.Stub                .asInterface(ServiceManager.getService(Context.MY_TEST_SERVICE));<span style="white-space:pre"></span>    mTestService = mService;<span style="white-space:pre"></span>}    /**<span style="white-space:pre"></span> * Return true if open succeed<span style="white-space:pre"></span> * <span style="white-space:pre"></span> * @see #open my Function()<span style="white-space:pre"></span> */<span style="white-space:pre"></span>public boolean openScanner() {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>    mTestService.open();<span style="white-space:pre"></span>} catch (android.os.RemoteException e) {<span style="white-space:pre"></span>    return false;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return true;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * Return true if close succeed<span style="white-space:pre"></span> * <span style="white-space:pre"></span> * @see #close my Function()<span style="white-space:pre"></span> */<span style="white-space:pre"></span>public boolean closeScanner() {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>    mTestService.close();<span style="white-space:pre"></span>} catch (android.os.RemoteException e) {<span style="white-space:pre"></span>    return false;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return true;<span style="white-space:pre"></span>}}</span>
<span style="font-family: arial;">這個Manager通過aidl的</span>Stub擷取了剛才添加的那個系統層級的service,然後在這裡去調用這個service的方法,以操作service,這就是aidl的作用。
<span style="font-family: arial;">然後我們可以寫一個第三方程式,擷取一個</span><span style="font-family: arial;">MyTestManager,調用這個管理類的</span><span style="font-family: arial;">openScanner和closeScanner方法去實現自己在service中定義的功能。</span>
<span style="font-family: arial;">AndroidManifest中必須要添加<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>許可權,否則報錯,沒有研究這個許可權起的什麼作用,有懂得的朋友分享一下吧。</span>
<span style="font-family: arial;">import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.app.Activity;import android.device.MyTestManager;public class MainActivity extends Activity {<span style="white-space:pre"></span>private Button open, close;<span style="white-space:pre"></span>private MyTestManager mTestManager;<span style="white-space:pre"></span><span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>protected void onCreate(Bundle savedInstanceState) {<span style="white-space:pre"></span>super.onCreate(savedInstanceState);<span style="white-space:pre"></span>setContentView(R.layout.activity_main);<span style="white-space:pre"></span><span style="white-space:pre"></span>mTestManager = new MyTestManager();<span style="white-space:pre"></span>open = (Button) findViewById(R.id.btn1);<span style="white-space:pre"></span>open.setText("開啟Wifi");<span style="white-space:pre"></span>close = (Button) findViewById(R.id.btn2);<span style="white-space:pre"></span>close.setText("關閉Wifi");<span style="white-space:pre"></span><span style="white-space:pre"></span>open.setOnClickListener(new OnClickListener() {<span style="white-space:pre"></span><span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void onClick(View v) {<span style="white-space:pre"></span>// TODO Auto-generated method stub<span style="white-space:pre"></span>mTestManager.openScanner();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>});<span style="white-space:pre"></span><span style="white-space:pre"></span>close.setOnClickListener(new OnClickListener() {<span style="white-space:pre"></span><span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void onClick(View v) {<span style="white-space:pre"></span>// TODO Auto-generated method stub<span style="white-space:pre"></span>mTestManager.closeScanner();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>});<span style="white-space:pre"></span>}}</span>
<span style="font-family: arial;">這也就實現了Android誇進程通訊了。</span>
<span style="font-family:arial;">這裡只是一個很簡單的例子,以便不理解這一塊的朋友管中窺豹,其實AIDL和系統級服務的配合使用遠沒這麼簡單,但是大致原理是這樣的,比如Android的網路服務,google定義了很多的狀態,通過背景Service不斷的監聽這些狀態的變化去控制網路,又比如電源管理,控制螢幕的亮度等等,複雜的是其中繁多的狀態變化。</span>
<span style="font-family:arial;"></span>
<span style="font-family:arial;">文章寫的比較淺顯,希望大家多多指教。</span>



AIDL在android系統中的作用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.