在開始本章之前,先向大家介紹COM的一個概念---------Proxy/Stub結構(代理/存根結構)
vcHt0rvNt6Os0vjQ0LXEt/7O8cb3o6zL+9Kyw7vT0LHY0qrWqrXAxOPU2sTEtvnIoceuo6zL+8v5udjQxLXEysfE47XEye233aOsus3E48ihv+624MnZoaO1scv7yLfIz8TjtcTIqM/eo6y+zb340NDP4NOmtcSy2df3o6y3tbvYstnX973hufu4+Mihv+67+qOsyKG/7rv6uPm+3bf+zvHG97e1u9i94bn7o6y007Gjz9W58cDvyKGz9s/g06bK/cG/tcTHrrj4xOOho8TjyKGz9r+ouvOjrLLZ1/fN6rPJoaPIob/uu/qyu8rH1rG9082st/7O8cb3way907XEo6zL+8PH1q685Lu509DSu7j2obC05rj5obGjrMihv+67+tPrtOa4+c2o0MWjrLf+zvHG99PrtOa4+c2o0MWho7TTxLPW1tLi0uXJz8u1tOa4+b7Nyse3/s7xxve1xLT6wO2hozwvcD4KPHA+QUlETEZyYW1ld29ya7LjtcS83Lm5o6zI58/CzbyjujwvcD4KPGltZyBzcmM9"http://www.2cto.com/uploadfile/Collfiles/20140417/2014041709210782.gif" alt="\">
Android就是在傳統的C/S架構中加入了一層,實現IPC。我們下面來詳細介紹一下android的aidl實現原理
AIDL(Android介面定義語言)是類似於其他你遇到過的IDL。它允許您定義的編程介面,用戶端和服務達成一致,以互相交流使用處理序間通訊(IPC)。在Android上,一個進程無法正常訪問另一個進程的記憶體,而AIDL可以為你實現。AIDL的使用呢和我之前寫的Messenger的使用有著很大的區別,我們先要搭建一個aidl服務端,搭建服務端有以下三個步驟(1)建立aidl檔案,這個檔案將定義方法簽名的編程介面。當你構建aidl檔案,Android SDK工具將自動產生一個基於內部的介面。,並將aidl檔案其儲存在項目的創/目錄。(2)實現介面.Android SDK工具自動產生的基於aidl介面的Java程式設計語言介面。這個介面有一個名為stub的內在抽象類別,擴充了ibinder從AIDL介面和實現方法。你必須擴充Stub類和並且實現方法。(3)公開介面給用戶端。實現一個Service並覆蓋onBind()返回你的stub類的實現。
伺服器端架構
DataService.aidl原始碼如下:
package com.example.service;interface DataService{ int getData(String name);}
MyService的原始碼:
package com.example.f25_aidl01;import com.example.service.DataService;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class MyService extends Service {@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();}private final DataService.Stub mBinder=new DataService.Stub(){@Overridepublic int getData(String name) throws RemoteException {// TODO Auto-generated method stubif(name.equals("1")){return 1;}return 0;}};@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn mBinder;}}
在啟動Client之前先要啟動伺服器端的Service,並在資訊清單檔如下寫到
Client要注意必須和服務端一樣聲明一個一摸一樣的aidl檔案。
MainAcitivity的原始碼
package com.example.f25_aidl_client;import com.example.service.DataService;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.util.Log;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity {private Button button, button2;private DataService dataService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (Button) this.findViewById(R.id.button1);button2 = (Button) this.findViewById(R.id.button2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubIntent intent = new Intent(DataService.class.getName());bindService(intent, connection, Context.BIND_AUTO_CREATE);}});button2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtry {int a = dataService.getData("1");Toast.makeText(MainActivity.this, "---->"+a, Toast.LENGTH_LONG).show();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubLog.i("TAG", "-------->unbind");}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubdataService = DataService.Stub.asInterface(service);}};@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}