一、AIDL (Android Interface Definition Language )java
二、AIDL 適用於 進程間通訊,而且與Service端多個線程併發的狀況,若是隻是單個線程 可使用 Messenger ,若是不須要IPC 可使用Binderandroid
三、AIDL語法:基礎數據類型均可以適用,List Map等有限適用。static field 不適用。服務器
四、AIDL基本用法併發
第一步:實現.aidl文件app
接口描述文件 1、導入的包名 2、若是有使用Object對象,須要該對象 implement Parcelable 接口,而且須要導入該接口包名+類名; 若是是primitive type 不須要這步。 3、定義方法名稱。 4、全部的.aidl文件以及須要傳遞的對象接口須要在Service 與Client中各一份 package com.aidl; import com.aidl.Data; interface IaidlData { int getPid(); String getName(); com.aidl.Data getData(); }
二、在Service中實現.aidl 接口。實際實現的接口是在 gen中自動生成的 IaidlData.java的抽象內部類 Stubspa
1、須要在配置文件Androidmanifest.xml文件中聲明Service,而且添加intent-filter 節點 的action屬性, 此屬性通常可使用 aidl的包名+文件名(由於該值在服務器與客戶端一致) 2、須要實現IaidlData.aidl文件中定義的接口。 aidl文件是一個接口描述文件,會在gen中自動生成一個同名的IaidlData.java接口文件,該接口文件包含一個抽象類stub,其繼承了android.os.Binder、實現IaidlData接口 故,咱們實際須要實現的是Stub抽象類。 public class AidlService extends Service { public void onCreate() { Log.d("aidl", "aidlService--------------onCreate"); } public IBinder onBind(Intent intent) { return mBinder; } private final IaidlData.Stub mBinder = new IaidlData.Stub() { public int getPid() { return Process.myPid(); } public String getName() throws RemoteException { return "go or not go is a problem"; } public Data getData() throws RemoteException { Data data = new Data(); data.id = Process.myPid(); data.name = "go or not go is a problem"; return data; } }; }
三、綁定Service ,而且獲取IaidlService 對象線程
1、創建鏈接,使用Action屬性定位須要的Service actoin的屬性的採用aidl文件的類名+包名(與服務一致),以前須要在服務中設置相同的action屬性,不然找不到服務。 2、獲取服務返回的stub對象,mIaidlData = IaidlData.Stub.asInterface(service); package com.clent; import com.aidl.IaidlData; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.View; public class AidlClientActivity extends Activity { IaidlData mIaidlData; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } protected void onStart() { super.onStart(); Log.d("aidl" , "onstart ----------bindservice-----"+IaidlData.class.getName()); Intent intent = new Intent(IaidlData.class.getName()); bindService(intent, mSecondaryConnection, BIND_AUTO_CREATE); } private ServiceConnection mSecondaryConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { Log.d("aidl", "onServiceConnected----------------"); mIaidlData = IaidlData.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName className) { mIaidlData = null; } }; public void onClick(View view) { System.out.println( " onclick--------------- : "); if(mIaidlData != null) { try { System.out.println( " name : "+mIaidlData.getName()); System.out.println( " id : "+mIaidlData.getPid()); System.out.println( " data : "+mIaidlData.getData().id +" "+mIaidlData.getData().name); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } protected void onDestroy() { super.onDestroy(); unbindService(mSecondaryConnection); } }
四、若是aidl文件中須要傳遞Object對象,須要添加對應的.aidl文件code
1、定義該對象Data,並實現Parcelable 2、添加Data.aidl文件,並採用以下方式編寫導入Data 3、須要在引用到Data的.aidl文件中 import com.aidl.Data 4、須要在 服務端 和 客戶端 都添加 Data.aidl與 Data.java文件 而且須要一致。 Data.aidl aidl文件: package com.aidl; parcelable Data;
五、添加 對應的Object類,而且實現Parcelable接口xml
public class Data implements Parcelable { public int id; public String name; public static final Parcelable.Creator<Data> CREATOR = new Parcelable.Creator<Data>() { public Data createFromParcel(Parcel in) { return new Data(in); } public Data[] newArray(int size) { return new Data[size]; } }; public Data() { } private Data(Parcel in) { readFromParcel(in); } public void readFromParcel(Parcel in) { id = in.readInt(); name = in.readString(); } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); } }