包含.aidl文件的应用,SDK工具会生成一个基于.aidl文件的Ibinder的接口,保存在项目的gen/ 目录中,服务实现IBinder接口,客户端绑定服务调用IBinder来实现IPC.
注意:server中必须是Arraylist 或者HashMap 。非原语要指示数据走向(in、out、inout)原语默认in。要确定好你需要的方向,因为编组参数开销极大。in –>数据从客户端流向服务端,out 数据只能由服务端流向客户端,inout 则表示数据可在服务端与客户端之间双向流通。其中,数据流向是针对在客户端中的那个传入方法的对象而言的。in 为定向 tag 的话表现为服务端将会接收到一个那个对象的完整数据,但是客户端的那个对象不会因为服务端对传参的修改而发生变动;out 的话表现为服务端将会接收到那个对象的参数为空的对象,但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动;inout 为定向 tag 的情况下,服务端将会接收到客户端传来对象的完整信息,并且客户端将会同步服务端对该对象的任何变动来自 https://blog.csdn.net/luoyanglizi/article/details/51958091
这个aidl类要和Parcelable实现名字一样。
要让服务端先起来 客户端才能绑定服务 而且现在只能显示绑定服务。
先创建.aidl文件
package com.music.fiio.aidldemo; import com.music.fiio.aidldemo.Person; // Declare any non-default types here with import statements interface IServiceAIDL { void addPerson(in Person p); // 对于非原语的数据类型要加tag ListgetPerson(); }
那么如何去得到想要去传递的自定义类
首先创建一个.aidl文件,这个文件名和你想要的实体类名保持一致。
Person.aidl文件
注意其中的 parcelable 的首字母是小写哦。
接下来就是创建实现Parcelable的实体类
public class Person implements Parcelable { private String name ; private int age ; public Person(){} protected Person(Parcel in) { readFromParcel(in); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); } /** * 参数是一个Parcel,用它来存储与传输数据 * @param dest */ public void readFromParcel(Parcel dest) { //注意,此处的读值顺序应当是和writeToParcel()方法中一致的 name = dest.readString(); age = dest.readInt(); } @Override public int describeContents() { return 0; } public static final CreatorCREATOR = new Creator () { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @Override public Person[] newArray(int size) { return new Person[size]; } }; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
你可以手动的去clean下项目 IDE会在在build中的gen中生成一个.java的文件,其实我们操作也是这个文件。
现在让我们来创建一个服务
public class DemoService extends Service { Listlists = new ArrayList<>(); @Override public void onCreate() { super.onCreate(); Person person ; for (int i = 0 ; i < 10 ; i ++){ person = new Person(); person.setAge(i); person.setName(i+"号机器人"); lists.add(person); } Log.i("zxy--",""); } @Nullable @Override public IBinder onBind(Intent intent) { Log.i("zxy - ","onBind"); return mbinder; } private IBinder mbinder = new IServiceAIDL.Stub(){ @Override public void addPerson(Person p) throws RemoteException { synchronized (lists){ lists.add(p); } } @Override public List getPerson() throws RemoteException { synchronized (lists){ return lists ; } } }; }
记得要去AndroidManifest.xml中注册:
android:name=".DemoService"
android:exported="true"
>
android:name="android.intent.category.DEFAULT"/>
android:name="com.music.fiio.aidldemo.DemoService"/>
到这里简单的服务其实就ok了。
现在我们可以来做客户端:
我们将服务端的包含aidl的包都复制到客户端来,当然还有实体类也要复制过来,而且要保证他们的包名和服务端是一样de。
这样其实也会在build下生成一个.java文件。
客户端代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private IServiceAIDL iServiceAIDL ; private Button button_get; private Button button_add; // 需要等Service的的app先启动起来 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button_get = (Button)findViewById(R.id.button_get); button_get.setOnClickListener(this); button_add = (Button)findViewById(R.id.button_add); button_add.setOnClickListener(this); Intent intent = new Intent(); intent.setPackage("com.music.fiio.aidldemo"); intent.setAction("com.music.fiio.aidldemo.DemoService"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); bindService(intent,connection,BIND_AUTO_CREATE); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.button_add: try { Person p = new Person(); p.setName("new 机器人"); p.setAge(22); iServiceAIDL.addPerson(p); }catch (Exception e){ e.printStackTrace(); } break; case R.id.button_get: try { List到这里简单的aidl通信完成了,当然aidl不止这么简单,后来需要大佬们自己去学习了。lists = iServiceAIDL.getPerson(); for (Person p : lists){ Log.i("zxy-","person - name : "+p.getName()+" - age : "+p.getAge()); } }catch (Exception e){ e.printStackTrace(); } break; } } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { iServiceAIDL = IServiceAIDL.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { Log.i("zxy-","onServiceDisconnected "); } }; }