Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
创建.aidl文件
跟创建一个接口文件一样创建.aidl文件。Eclipse编译后会放在gen目录下。Android Studio直接创建AIDL目录,跟java目录同级,直接创建AIDL文件。Android Studio默认不编译,需要编译后才会在Debug目录下显示出来。实现接口(Implement the interface)
创建一个继承Service的类,里面创建一个IBinder来实现Aidl.Stub里面的方法的IBinder类型的变量。共享接口给客户端(Expose the interface to clients)
将onBind方法返回的IBinder设置成定义的IBinder变量。客户端那里同样创建一个.aidl文件,同样的包名。
客户端绑定Service,使用Intent显示Intent启动,在5.0以后不支持隐式调用。 Intent intent = new Intent(); // 新版本5.0必须显式Intent启动绑定服务 intent.setcomponent(new ComponetName("包名","包名.类名"); 客户端绑定Service, bindService(intent, conn, Context.BIND_AUTO_CREATE);。客户端创建ServiceConnection变量,实现接口。 private ServiceConnection conn = new ServiceConnection(){ // 绑定服务的时候 @Overrive public void onServiceConnected(ComponentName name, IBinder service){ // 拿到远程服务 iImoocAidl = IImoocAidl.Stub.asInterface(service); } // 断开服务的时候 @Overrive public void onServiceDisconnected(ComponentName name){ iImoocAidl = null; } } 服务端的AndroidManifest.xml文件中添加service,需要添加name,exported,enabled,process。客户端使用接口定义的方法。服务端创建实现Parcelable的实体类,如Person,创建构造方法、get、set方法,并且重写未实现的方法。
在writeToParcel(Parcel dest, int flags)方法里面写入数据。
@Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } 创建CREATOR变量,在createFromParcel(Parcel source)方法里面返回new Person(source)。 public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person[] newArray(int size) { return new Person[size]; } @Override public Person createFromParcel(Parcel source) { return new Person(source); } }; 创建相应的构造方法,并且按顺序读取数据。 public Person(Parcel source) { // 按顺序 this.name = source.readString(); this.age = source.readInt(); }创建实体类对应的aidl文件,如Person.aidl。parcelable Person;
在主aidl文件内import对应的实体类,并且创建对应的方法,Parcelable也要设置in或out或inout属性。
import com.example.aidlservice.Person; interface AidlTestInterface { List<Person> add(in Person person); } 设置Service。 private ArrayList<Person> persons; @Override public IBinder onBind(Intent intent) { persons = new ArrayList<Person>(); return iBinder; } private AidlTestInterface.Stub iBinder = new Stub() { @Override public List<Person> add(Person person) throws RemoteException { persons.add(person); return persons; } };将对应的实体类文件,实体类aidl文件,主aidl文件复制到客户端,包名必须一致。
客户端调用对应的方法。
* Stub.asInterface(Ibinder)访问的是Proxy。 * Proxy通过发送code请求给Stub里面的OnTransact方法。