Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之IPC進程間通信-AIDL介紹及實例解析

Android開發之IPC進程間通信-AIDL介紹及實例解析

編輯:關於Android編程

一、IPC進程間通信   IPC是進程間通信方法的統稱,Linux IPC包括以下方法,Android的進程間通信主要采用是哪些方法呢?      1. 管道(Pipe)及有名管道(named pipe):管道可用於具有親緣關系進程間的通信,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關系進程間的通信;    2. 信號(Signal):信號是比較復雜的通信方式,用於通知接受進程有某種事件發生,除了用於進程間通信外,進程還可以發送信號給進程本身;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標准的信號函數sigaction(實際上,該函數是基於BSD的,BSD為了實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數);    3. 報文(Message)隊列(消息隊列):消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩沖區大小受限等缺點。    4. 共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。    5. 信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。    6. 套接口(Socket):更為一般的進程間通信機制,可用於不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支持套接字。   二、AIDL(Android Interface Definition Language)   AIDL - Android Interface Definition Language - Android 接口定義語言。因為在Android中,應用程序運行在各自獨立的進程裡。應用程序之間是不能訪問對方的內存空間的。有時為了實現進程間的通信,要用到PCI機制。Android支持PCI機制,但是需要Android能讀懂的序列化數據(marshaling/un marshaling of data).    AIDL就是為了描述這樣的數據產生的,它是一種接口定義語言。語法類似JAVA,.aidl文件裡面寫的是公布給客戶端接口聲明。   本文中,為了吸取客戶端,服務器端兩個android 項目的經驗,將兩段整合到一個android項目裡,這樣可能會比較清晰。下面就看看實例解析吧。   三、AIDL介紹及解析   1.AIDL介紹   在Android中,每個應用(Application)執行在它自己的進程中,無法直接調用到其他應用的資源,這也符合“沙箱”的理念。所謂沙箱原理,一般來說用在移動電話業務中,簡單地說旨在部分地或全部地隔離應用程序。關於沙箱技術我們這裡就不多做介紹了。因此,在Android中,當一個應用被執行時,一些操作是被限制的,比如訪問內存,訪問傳感器,等等。這樣做可以最大化地保護系統,免得應用程序“為所欲為”。那我們有時需要在應用間交互,怎麼辦呢?於是,Android需要實現IPC協議。然而,這個協議還是有點復雜,主要因為需要實現數據管理系統(在進程或線程間傳遞數據)。Android為我們實現了自己的IPC,也就是AIDL。   2.定義AIDL接口   AIDL是IPC的一個輕量級實現,用了對於Java開發者來說很熟悉的語法。Android也提供了一個工具,可以自動創建Stub(類構架,類骨架)。當我們需要在應用間通信時,我們需要按以下幾步走:   a. 定義一個AIDL接口   b. 為遠程服務(Service)實現對應Stub   c. 將服務“暴露”給客戶程序使用   3.實例解析   AIDL的語法很類似Java的接口(Interface),只需要定義方法的簽名。   AIDL支持的數據類型與Java接口支持的數據類型有些不同   a. 所有基礎類型(int, char, 等)   b. String,List,Map,CharSequence等類   c. 其他AIDL接口類型   d. 所有Parcelable的類   下面以一個加法器為例來做解析。   (1)創建工程,創建AIDL接口:新建一個文件,命名為IAdditionService.aidl 即可   package com.czm.hellosumaidl;   interface IAdditionService{     int add(int value1,int value2); } 一旦文件被保存,Android的AIDL工具會在 gen/com/android/hellosumaidl 這個文件夾裡自動生成對應的 IAdditionService.java 這個文件。因為是自動生成的,所以無需改動。這個文件裡就包含了 Stub ,我們接下來要為我們的遠程服務實現這個Stub。   (2)實現遠程服務   首先我們新建一個類,取名叫AdditionService.java 。為了 實現我們 的服務,我們需要讓 這個 類中的 onBind方法返回一個 IBinder 類的對象。這個 IBinder 類的對象就代表了遠程服務的實現。為了實現這個服務,我們要用到自動生成的子類 IAdditionService.Stub 。在其中,我們也必須實現我們之前在AIDL文件中定義的 add() 函 數。下面是我們遠程服務的代碼:   復制代碼 public class AdditionService extends Service{       @Override       public void onCreate() {           super.onCreate();       }                     @Override     public IBinder onBind(Intent intent) {         // TODO Auto-generated method stub         return new IAdditionService.Stub() {                          @Override             public int add(int value1, int value2) throws RemoteException {                 // TODO Auto-generated method stub                 return value1 + value2;             }         };     }          @Override       public void onDestroy() {           super.onDestroy();       }    } 復制代碼 (3)提供服務(“暴露”服務給使用者)   一旦實現了服務中的onBind方法 ,我們就可以把客戶程序(在這裡是MainActivity.java )與服務連接起來了。為了建立這樣的一個鏈接 ,我們需要實現 ServiceConnection 類。我們在 MainActivity.java 創建一個內部類 AdditionServiceConnection ,這個類繼承 ServiceConnection 類,並且重寫了它的兩個方法: onServiceConnected 和 onServiceDisconnected。下面給出 內部類的代碼:   復制代碼 class AdditionServiceConnection implements ServiceConnection {           @Override         public void onServiceConnected(ComponentName name, IBinder boundService) {             // TODO Auto-generated method stub             service = IAdditionService.Stub.asInterface((IBinder) boundService);             Toast.makeText(MainActivity.this, "Service connected",                     Toast.LENGTH_SHORT).show();         }           @Override         public void onServiceDisconnected(ComponentName name) {             // TODO Auto-generated method stub             service = null;             Toast.makeText(MainActivity.this, "Service disconnected",                     Toast.LENGTH_SHORT).show();         }       } 復制代碼 (4)相關代碼及效果截圖   MainActivity.java的全部代碼如下:   復制代碼 package com.czm.hellosumaidl;   import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast;   public class MainActivity extends Activity {       IAdditionService service;     AdditionServiceConnection connection;     EditText value1;     EditText value2;     TextView result;     Button buttonCalc;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);         initService();           buttonCalc = (Button) findViewById(R.id.buttonCalc);           value1 = (EditText) findViewById(R.id.value1);         value1.setText("23");         value2 = (EditText) findViewById(R.id.value2);         value2.setText("24");         result = (TextView) findViewById(R.id.result);         buttonCalc.setOnClickListener(new OnClickListener() {                            @Override             public void onClick(View v) {                 int v1, v2, res = -1;                 v1 = Integer.parseInt(value1.getText().toString());                 v2 = Integer.parseInt(value2.getText().toString());                   try {                     res = service.add(v1, v2);                 } catch (RemoteException e) {                     e.printStackTrace();                 }                   result.setText(Integer.valueOf(res).toString());             }         });     }       @Override     protected void onDestroy() {         super.onDestroy();         releaseService();     }       /*      * This function connects the Activity to the service      */     private void initService() {         connection = new AdditionServiceConnection();                  Intent i = new Intent();         i.setClassName("com.czm.hellosumaidl",com.czm.hellosumaidl.AdditionService.class.getName());         boolean ret = this.bindService(i, connection, Context.BIND_AUTO_CREATE);     }       /*      * This function disconnects the Activity from the service      */     private void releaseService() {         unbindService(connection);         connection = null;     }       class AdditionServiceConnection implements ServiceConnection {           @Override         public void onServiceConnected(ComponentName name, IBinder boundService) {             // TODO Auto-generated method stub             service = IAdditionService.Stub.asInterface((IBinder) boundService);             Toast.makeText(MainActivity.this, "Service connected",                     Toast.LENGTH_SHORT).show();         }           @Override         public void onServiceDisconnected(ComponentName name) {             // TODO Auto-generated method stub             service = null;             Toast.makeText(MainActivity.this, "Service disconnected",                     Toast.LENGTH_SHORT).show();         }       }   }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved