AIDL(Android 接口定義語言) 是 Android 提供的一種進程間通訊 (IPC) 機制。java
咱們能夠利用它定義客戶端與服務使用進程間通訊 (IPC) 進行相互通訊時都承認的編程接口。android
在 Android 上,一個進程一般沒法訪問另外一個進程的內存。 儘管如此,進程須要將其對象分解成操做系統可以識別的原語,並將對象編組成跨越邊界的對象。編程
編寫執行這一編組操做的代碼是一項繁瑣的工做,所以 Android 會使用 AIDL 來處理。app
經過這種機制,咱們只須要寫好 aidl 接口文件,編譯時系統會幫咱們生成 Binder 接口。dom
共 4 種:ide
AIDL 的編寫主要爲如下三部分:this
Parcelable
接口,以便序列化/反序列化onBind()
中返回ServiceConnection
接口,在其中拿到 AIDL 類bindService()
項目結構圖:spa
Parcelable
接口,以便序列化/反序列化package net.shunzhi.aidldemo1.bean; import android.os.Parcel; import android.os.Parcelable; /** * Created by Administrator on 2018/3/9 0009. */ public class Person implements Parcelable { private String mName; public Person (String name){ this.mName=name; } protected Person(Parcel source){ this.mName=source.readString(); } public static final Creator<Person> CREATOR=new Creator<Person>() { @Override public Person createFromParcel(Parcel source) { return new Person(source); } @Override public Person[] newArray(int size) { return new Person[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); } @Override public String toString() { return "Person{" + "mName='" + mName + '\'' + '}'; } }
1.鼠標移到項目上面去,點擊右鍵,而後 new->AIDL->AIDL File,按下鼠標左鍵就會彈出一個框提示生成AIDL文件(IMyAIdlInterface)了操作系統
自動生成如圖:代理
2.編寫接口IMyAdilInterface.aidl
// IMyAidlInterface.aidl //第二類AIDL文件 //做用是定義方法接口 package net.shunzhi.aidldemo1; ////導入所須要使用的非默認支持數據類型的包 import net.shunzhi.aidldemo1.bean.Person; interface IMyAidlInterface { //傳參時除了Java基本類型以及String,CharSequence以外的類型 //都須要在前面加上定向tag,具體加什麼量需而定:in(輸入), out(輸出), inout(輸入輸出) void addPerson(in Person person); //全部的返回值前都不須要加任何東西,無論是什麼數據類型 List<Person> getAllPersons(); }
在接口 aidl 文件中定義未來要在跨進程進行的操做,上面的接口中定義了兩個操做:
須要注意的是:
3.建立實體類Person.aidl
//第一類AIDL文件 //這個文件的做用是引入了一個序列化對象 Book 供其餘的AIDL文件使用 //注意:Person.aidl與Person.java的包名應當是同樣的 package net.shunzhi.aidldemo1.bean; //parcelable 爲小寫 parcelable Person;
onBind()
中返回
package net.shunzhi.aidldemo1; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.support.annotation.Nullable; import net.shunzhi.aidldemo1.bean.Person; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2018/3/9 0009. */ public class MyAidlService extends Service { private String TAG="MyAidlService"; private List<Person> list; /** * 建立生成的本地 Binder 對象,實現 AIDL 制定的方法 */ private IBinder iBinder=new IMyAidlInterface.Stub() { @Override public void addPerson(Person person) throws RemoteException { list.add(person); } @Override public List<Person> getAllPersons() throws RemoteException { return list; } }; /** * 客戶端與服務端綁定時的回調,返回 mIBinder 後客戶端就能夠經過它遠程調用服務端的方法,即實現了通信 * @param intent * @return */ @Nullable @Override public IBinder onBind(Intent intent) { list=new ArrayList<>(); return iBinder; } }
<service android:name=".MyAidlService" android:enabled="true" android:exported="true" android:process=":aidl" />
ServiceConnection
接口,在其中拿到 AIDL 類private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//鏈接後拿到 Binder,轉換成 AIDL,在不一樣進程會返回個代理
aidl=IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
aidl=null;
}
};
在 Activity 中建立一個服務鏈接對象,在其中調用 IMyAidl.Stub.asInterface()
方法將 Binder 轉爲 AIDL 類
Intent intent=new Intent(MainActivity.this,MyAidlService.class); bindService(intent,connection,BIND_AUTO_CREATE);
private void addPerson(){ Random random=new Random(); Person p=new Person("fhasdfh"+random.nextInt(10) ); try { aidl.addPerson(p); tv.setText(aidl.getAllPersons().toString()); } catch (RemoteException e) { e.printStackTrace(); } }
總體代碼:
package net.shunzhi.aidldemo1; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import net.shunzhi.aidldemo1.bean.Person; import java.util.Random; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv; private Button bt1,bt2; private IMyAidlInterface aidl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { tv=findViewById(R.id.tv); bt1=findViewById(R.id.bt1); bt2=findViewById(R.id.bt2); bt1.setOnClickListener(this); bt2.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt1://綁定服務 Intent intent=new Intent(MainActivity.this,MyAidlService.class); bindService(intent,connection,BIND_AUTO_CREATE); break; case R.id.bt2: addPerson(); break; } } //拿到 AIDL 類後,就能夠調用 AIDL 類中定義好的操做,進行跨進程請求 private void addPerson(){ Random random=new Random(); Person p=new Person("fhasdfh"+random.nextInt(10) ); try { aidl.addPerson(p); tv.setText(aidl.getAllPersons().toString()); } catch (RemoteException e) { e.printStackTrace(); } } private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //鏈接後拿到 Binder,轉換成 AIDL,在不一樣進程會返回個代理 aidl=IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { aidl=null; } }; }
效果圖: