AIDL在android系統中的作用

來源:互聯網
上載者:User

標籤:

AIDL,Android Interface definition language的縮寫,它是一種android內部進程通訊介面的描述語言,通過它我們可以定義進程間的通訊介面。最近看了下AIDL在Android系統中的用法,在網上看到很多初學的朋友不太明白AIDL的實際作用,android提供了很多處理序間通訊的組件,像action、broadcast、contentprovide都可以實現進程間的通訊,為什麼還要用AIDL這個東西呢?我在android源碼中實現了一個自己寫的AIDL例子,用以簡單解釋下AIDL的作用。

有開發過藍芽或者WIFI應用的朋友肯定都知道,要去操作它必須先獲得一個管理類,比如WIFI的管理類是WifiManager,通過getSystemService(Context.WIFI_SERVICE)就可以得到wifi的系統管理權限,這個提供了很多的方法可以讓使用者去操作它,比如開啟wifi可以調用setWifiEnabled(true)方法。那這個Manager到底做了什麼工作呢?是怎樣實現開啟wifi的呢?其實這個Manager只是一個管理類,真正幹活的另有其人,是一個叫WifiService的系統服務。在Android系統中有很多的Manager,wifi的管理類叫WifiManager,藍芽的管理類叫BluetoothManager,但是,只要有xxxManager.java,就會有Ixxx.aidl,並且有xxxService.java。這個aidl類就是實現Manager和Service通訊的橋樑。

下面看我加的一個例子:

首先在android源碼中的frameworks/base/core/java/android/os/目錄下加入一個IMyTestService.aidl,一般系統的AIDL檔案都放在這個目錄下。

 

?
12345678 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。

 

?
12345678910111213141516171819202122232425262728 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方法中添加下面代碼:

 

 

?
1234567 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);             }

 

myService需要在前面聲明一下。

SystemService是android系統跑起來之後就會調用的,這裡的意思是把MyTestService添加到系統服務中去,並取名字叫Context.MY_TEST_SERVICE,也就是my_test_service。這樣看起來是不是很熟悉呢?每個開發人員在開發過程中肯定會調用系統服務的,比如電源管理服務:getSystemService(Context.POWER_SERVICE),這個Service也是在這裡添加進去的。android有很多的系統服務,這裡就不一一例舉了,有興趣的朋友可以自行看看這個檔案。

 

現在aidl添加了,service也添加了,並且添加進了系統服務,那麼還少一個Manager,可以讓第三方程式調用的Manager。

在frameworks/base/core/java/android/device/目錄下添加MyTestManager.java檔案:

 

 

?
12345678910 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 { private static final String TAG = "MyTestManager";
?
1234567891011121314151617181920212223242526272829303132 private IMyTestService mTestService;     public MyTestManager() {        IMyTestService mService = IMyTestService.Stub                .asInterface(ServiceManager.getService(Context.MY_TEST_SERVICE));        mTestService = mService;    }    /**     * Return true if open succeed     * @see #open my Function()     */    public boolean openScanner() {        try {            mTestService.open();        } catch (android.os.RemoteException e) {            return false;        }        return true;    }    /**     * Return true if close succeed     * @see #close my Function()     */     public boolean closeScanner() {         try {              mTestService.close();         } catch (android.os.RemoteException e) {              return false;         }         return true;    }}

 

這個Manager通過aidl的Stub擷取了剛才添加的那個系統層級的service,然後在這裡去調用這個service的方法,以操作service,這就是aidl的作用。

然後我們可以寫一個第三方程式,擷取一個MyTestManager,調用這個管理類的openScanner和closeScanner方法去實現自己在service中定義的功能。

AndroidManifest中必須要添加許可權,否則報錯,沒有研究這個許可權起的什麼作用,有懂得的朋友分享一下吧。

 

?
1234567891011121314151617181920212223242526272829303132333435363738394041 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 {    private Button open, close;    private MyTestManager mTestManager;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);         mTestManager = new MyTestManager();        open = (Button) findViewById(R.id.btn1);        open.setText("開啟Wifi");        close = (Button) findViewById(R.id.btn2);        close.setText("關閉Wifi");         open.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // TODO Auto-generated method stub                mTestManager.openScanner();            }       });         close.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {               // TODO Auto-generated method stub               mTestManager.closeScanner();            }        });    }}

 

這也就實現了Android誇進程通訊了。

這裡只是一個很簡單的例子,以便不理解這一塊的朋友管中窺豹,其實AIDL和系統級服務的配合使用遠沒這麼簡單,但是大致原理是這樣的,比如Android的網路服務,google定義了很多的狀態,通過背景Service不斷的監聽這些狀態的變化去控制網路,又比如電源管理,控制螢幕的亮度等等,複雜的是其中繁多的狀態變化。

文章寫的比較淺顯,希望大家多多指教。

 

推推族,免費得門票,遊景區:www.tuituizu.com

結伴旅遊,一個免費的交友網站:www.jieberu.com

 

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.