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; } }; }
效果图: