標籤:
前段時間研究了不少android二次開發,其中有一種方法就是通過aidl通訊,留介面提供給外面二次開發。從這裡也可以看出:aidl通訊是兩個應用程式之間的進程通訊了。在這篇部落格中,主要寫了兩個應用程式,一個是serverdemo,可以稱為服務端,也是提供介面的應用程式,在這裡面我寫了一個加法計算。二是用戶端:clientdemo,在這個程式中調用了加法計算介面,把值傳到serverdemo進行加法計算,返回結果,進行顯示。
1、aidl的定義
aidl是 Android Interface definition language的縮寫,它是一種android內部進程通訊介面的描述語言,通過它我們可以定義進程間的通訊介面;icp:interprocess communication :內部進程通訊。
2、兩個項目結構以及實現效果
從上面圖中看以大概看出,服務端布局什麼都沒有,不過這裡面有加法計算的服務。而用戶端有兩個輸入框輸入兩個值,點擊計算。
3、server服務端3.1、建立建立你的aidl檔案
儲存你的aidl檔案,這個只要是在eclipse中開發,你的adt外掛程式會像資源檔一樣把aidl檔案編譯成java代碼產生在gen檔案夾下,不用手動去編譯:編譯產生AIDLService.java如我例子中代碼。
IBoardADDInterface.aidl
package com.example.server;import android.os.Bundle;/*** * System private API for talking with the caculate service. * * {@hide} */interface IBoardADDInterface{ int add(int nValue1,int nValue2);}自動把aidl檔案編譯成java代碼產生在gen檔案夾下IBoardADDInterface的介面代碼
/* * This file is auto-generated. DO NOT MODIFY. * Original file: C:\\Users\\southgnssliyc\\Desktop\\android aidl\\ServerDemo\\src\\com\\example\\server\\IBoardADDInterface.aidl */package com.example.server;/*** * System private API for talking with the caculate service. * * {@hide} */public interface IBoardADDInterface extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.example.server.IBoardADDInterface{private static final java.lang.String DESCRIPTOR = "com.example.server.IBoardADDInterface";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.example.server.IBoardADDInterface interface, * generating a proxy if needed. */public static com.example.server.IBoardADDInterface asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof com.example.server.IBoardADDInterface))) {return ((com.example.server.IBoardADDInterface)iin);}return new com.example.server.IBoardADDInterface.Stub.Proxy(obj);}@Override public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_add:{data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.add(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.example.server.IBoardADDInterface{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}@Override public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}@Override public int add(int nValue1, int nValue2) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(nValue1);_data.writeInt(nValue2);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();}finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public int add(int nValue1, int nValue2) throws android.os.RemoteException;}這代碼一看就是自動產生的。
3.2、服務端的計算加法實作類別,寫一個server
package com.example.server;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;/** * 服務端的計算加法實作類別 * @author mmsx * */public class CaculateAddService extends Service {//加法計算的服務final String CACULATE_ADD = "COM.CACULATE.ADD";//找到自訂服務@Overridepublic IBinder onBind(Intent intent) {if(intent.getAction().equals(CACULATE_ADD)){return mIBinder_CACULATE_ADD;}return null;}@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic void onCreate() {super.onCreate();}//aidl的介面實現private final IBinder mIBinder_CACULATE_ADD = new IBoardADDInterface.Stub() {@Overridepublic int add(int nValue1, int nValue2) throws RemoteException {Log.i("Show", String.valueOf(nValue1) + ",,," +String.valueOf(nValue2));return nValue1 + nValue2;}};}
既然你寫了一個service,那麼就要在AndroidManifest.xml中添加註冊
<service android:name="com.example.server.CaculateAddService" > <intent-filter> <action android:name="COM.CACULATE.ADD" > </action> </intent-filter> </service>
這個名稱是自訂的:COM.CACULATE.ADD。service的路徑com.example.server.CaculateAddService。
到這裡就寫完了這個服務端的應用程式,是不是很簡單。activity都沒寫什麼,因為只是用到裡面的一個service和aidl。
4、用戶端client4.1、把服務端的aidl拷到用戶端,代碼不變
package com.example.server;import android.os.Bundle;/*** * System private API for talking with the caculate service. * * {@hide} */interface IBoardADDInterface{ int add(int nValue1,int nValue2);}自動編譯產生的程式碼就不貼了。
.4.2、寫一個綁定計算服務的類CaculateManager
package com.example.clientdemo;import com.example.server.IBoardADDInterface;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;/** * 用戶端的服務計算管理類 * @author mmsx * */public class CaculateManager {//加法計算的服務final String CACULATE_ADD = "COM.CACULATE.ADD";//aidi介面服務IBoardADDInterface mService = null; /*** * 服務綁定 */ public void bindService(Context context) { mContext = context; context.bindService(new Intent(CACULATE_ADD),serviceConnection, Context.BIND_AUTO_CREATE); } Context mContext = null; /*** * 解除服務綁定 */ public void unbindService() { if (mContext != null) { mContext.unbindService(serviceConnection);} } /** * 加法計算 * @param nValue1 * @param nValue2 * @return 結果 */ public int caculateAdd(int nValue1,int nValue2) {if (mService == null)return 0;try {return mService.add(nValue1, nValue2);} catch (Exception e) {return 0;} } //服務和aidl介面綁定 private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {mService = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mService = IBoardADDInterface.Stub.asInterface(service);}};}這裡面有找到服務,解除服務。方法實現的介面。
4.3、activity輸入資料,調用介面
package com.example.clientdemo;import android.os.Bundle;import android.app.Activity;import android.view.View;import android.view.View.OnClickListener;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {CaculateManager caculateManager = new CaculateManager();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);caculateManager.bindService(this);findViewById(R.id.button1).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {EditText editText1 = (EditText)findViewById(R.id.editText1);EditText editText2 = (EditText)findViewById(R.id.editText2);int nValue1 = Integer.parseInt(editText1.getText().toString().trim());int nValue2 = Integer.parseInt(editText2.getText().toString().trim());int nResult = caculateManager.caculateAdd(nValue1, nValue2);TextView textView = (TextView)findViewById(R.id.textView1);textView.setText("計算結果:" + String.valueOf(nResult));}});}}xml代碼很簡單
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="使用aidi服務調用其他程式計算,返回結果" /> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="numberDecimal" > <requestFocus /> </EditText> <EditText android:id="@+id/editText2" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="numberDecimal" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="計算結果:" /> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="加法計算" /></LinearLayout>
最後,本文的部落格代碼:下載
Android aidl通訊詳解