赞
踩
客户端demo:https://github.com/hewind/AidlClientTest
服务端demo:https://github.com/hewind/AidlServerTest
实现功能:增加人员、删除人员、获取人员信息;
- public class PersonBean implements Parcelable {
-
- private String name;
-
- public PersonBean(String name) {
- this.name = name;
- }
- public String getName() {
- return name == null ? "" : name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public String toString() {
- return "PersonBean{" + "name='" + name + '\'' + '}';
- }
-
-
- protected PersonBean(Parcel in) {
- name = in.readString();
- }
- public static final Creator<PersonBean> CREATOR = new Creator<PersonBean>() {
- @Override
- public PersonBean createFromParcel(Parcel in) {
- return new PersonBean(in);
- }
- @Override
- public PersonBean[] newArray(int size) {
- return new PersonBean[size];
- }
- };
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel parcel, int i) {
- parcel.writeString(name);
- }
-
- //删除使用
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj){//自反性
- return true;
- }
- if (!(obj instanceof PersonBean)){//instanceof比较判断是否是同一类或者子父类关系
- return false;
- }
- if (this.name.equals(((PersonBean) obj).getName())){//判断是同一类或者子父类关系,再将Object类型强转为Students
- return true;
- }
- return false;
- }
- @Override
- public int hashCode() {
- return name.hashCode();
- }
- }
PersonBean实现Parcelable接口,目的为了跨进程传输,重写equals和hashCode方法目的为了使用删除;
- public interface PersonManagerInterface extends IInterface {
-
- //添加人数
- void addPerson(PersonBean personBean) throws RemoteException;
-
- //删除人数
- void deletePerson(PersonBean personBean) throws RemoteException;
-
- //获取人数
- List<PersonBean> getPerson() throws RemoteException;
- }
创建PersonManagerInterface接口,并实现IInterface接口,只有实现IInterface接口,才具备跨进程传输的基础能力,另外如果我们使用Android Studio自带的创建AIDL生成的aidl文件,也是继承了该IInterface接口,这里自己手动创建并继承效果是一样的。
- public class Proxy implements PersonManagerInterface {
-
- //远程binder对象
- private IBinder iBinder;
- //Binder ID
- private static final String DESCRIPTOR = "com.example.aidlservertest.Proxy.PersonManagerInterface";
-
- public Proxy(IBinder iBinder) {
- this.iBinder = iBinder;
- }
-
- //增加人数实现
- @Override
- public void addPerson(PersonBean personBean) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel replay = Parcel.obtain();
- try {
- data.writeInterfaceToken(DESCRIPTOR);
- if (personBean != null){
- data.writeInt(1);
- personBean.writeToParcel(data,0);
- }else {
- data.writeInt(0);
- }
- iBinder.transact(Stub.TRANSAVTION_addperson,data,replay,0);
- replay.readException();
- }finally {
- replay.recycle();
- data.recycle();
- }
- }
- //删除人数实现
- @Override
- public void deletePerson(PersonBean personBean) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel replay = Parcel.obtain();
- try {
- data.writeInterfaceToken(DESCRIPTOR);
- if (personBean != null){
- data.writeInt(1);
- personBean.writeToParcel(data,0);
- }else {
- data.writeInt(0);
- }
- iBinder.transact(Stub.TRANSAVTION_deleteperson,data,replay,0);
- replay.readException();
- }finally {
- replay.recycle();
- data.recycle();
- }
- }
- //查询人数实现
- @Override
- public List<PersonBean> getPerson() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel replay = Parcel.obtain();
- List<PersonBean> result;
- try {
- //写入一个校验
- data.writeInterfaceToken(DESCRIPTOR);
- //客户端调用到这个方法,走到iBinder.transact,此时会进入系统层处理,处理结果通过调用Stub的transact方法返回,系统层处理过程会阻塞在这行代码,直到处理完成,
- iBinder.transact(Stub.TRANSAVTION_getpersons,data,replay,0);
- //上面一行代码在系统处理成功后,返回结果,由于Stub的transact方法写入了一个【reply.writeNoException()】,这里reply进行读取异常
- replay.readException();
- //这里是Stub的transact方法处理返回的结果
- result = replay.createTypedArrayList(PersonBean.CREATOR);
- }finally {
- replay.recycle();
- data.recycle();
- }
- return result;
- }
-
- /**
- * 方法说明:返回当前获取到的服务端的IBander
- * 日期:2020-09-09 10:31
- */
- @Override
- public IBinder asBinder() {
- return iBinder;
- }
-
- }
- public abstract class Stub extends Binder implements PersonManagerInterface {
-
- //Binder ID
- private static final String DESCRIPTOR = "com.example.aidlservertest.Proxy.PersonManagerInterface";
-
- public Stub() {
- //attachInterface方法:向BinderService注册Binder服务。只有注册了binder,客户端才能查询到有这个binder对象,并使用它
- this.attachInterface(this,DESCRIPTOR);
- }
-
- @Override
- public IBinder asBinder() {
- return this;
- }
-
- //将服务端的Binder对象准换成客户端所需要的AIDL接口对象,
- public static PersonManagerInterface asInterface(IBinder iBinder){
- if ((iBinder==null)) {
- return null;
- }
- //查询当前进程,如果客户端和服务端位于同一进程,那么此方法返回的就是当前进程的Stub对象本身,否则返回服务端进程的Stub.proxy对象(服务端也有该Stub类)
- IInterface iin = iBinder.queryLocalInterface(DESCRIPTOR);
- if ((iin != null) && (iin instanceof PersonManagerInterface)) {
- return (PersonManagerInterface)iin;
- }
- //返回服务端的Stub.proxy对象
- return new Proxy(iBinder);
- }
-
- //这个方法运行在服务端中的Binder线程池当中,当客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法处理。
- @Override
- protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
- switch (code){
- case INTERFACE_TRANSACTION:
- reply.writeString(DESCRIPTOR);
- return true;
- case TRANSAVTION_addperson://增加人数
- //返回一个校验
- data.enforceInterface(DESCRIPTOR);
- PersonBean personBean = null;
- if (data.readInt() != 0){
- //读取PersonBean
- personBean = PersonBean.CREATOR.createFromParcel(data);
- }
- //接口方法回调出去,这里最终会走到服务端的Service类的IBinder回调中
- this.addPerson(personBean);
- //返回一个无异常
- reply.writeNoException();
- return true;
- case TRANSAVTION_deleteperson://删除人数
- data.enforceInterface(DESCRIPTOR);
- PersonBean personBean2 = null;
- if (data.readInt() != 0){
- personBean2 = PersonBean.CREATOR.createFromParcel(data);
- }
- this.deletePerson(personBean2);
- reply.writeNoException();
- return true;
- case TRANSAVTION_getpersons://获取人数
- data.enforceInterface(DESCRIPTOR);
- List<PersonBean> result = this.getPerson();
- reply.writeNoException();
- reply.writeTypedList(result);
- return true;
- }
- return super.onTransact(code, data, reply, flags);
- }
-
- //使用int型代替字符串传递来标识调用的是哪一个方法,属于性能优化
- public static final int TRANSAVTION_getpersons = IBinder.FIRST_CALL_TRANSACTION;
- public static final int TRANSAVTION_addperson = IBinder.FIRST_CALL_TRANSACTION + 1;
- public static final int TRANSAVTION_deleteperson = IBinder.FIRST_CALL_TRANSACTION + 2;
- }
- public class MainActivity extends AppCompatActivity {
-
- private Button button,button2,button3;
- private TextView textView;
-
- private PersonManagerInterface personManagerInterface;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- prePareAidl();
-
- textView = findViewById(R.id.textview);
- button = findViewById(R.id.button);
- button2 = findViewById(R.id.button2);
- button3 = findViewById(R.id.button3);
- //添加人员
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- PersonBean personBean = new PersonBean();
- personBean.setName("张三");
- try {
- personManagerInterface.addPerson(personBean);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- getPerson();
- }
- });
- //删除人员
- button2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- PersonBean personBean = new PersonBean();
- personBean.setName("张三");
- try {
- personManagerInterface.deletePerson(personBean);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- getPerson();
- }
- });
- //获取人员
- button3.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- getPerson();
- }
- });
- }
-
- /**
- * 方法说明:获取Person人数
- * 日期:2020-09-11 16:36
- */
- private void getPerson() {
- try {
- List<PersonBean> list = personManagerInterface.getPerson();
- String str = "";
- for (PersonBean p:list){
- str += p.getName()+", ";
- }
- textView.setText(str);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 方法说明:通过绑定远程service,初始化远程iBinder实例
- * 日期:2020-09-09 17:14
- */
- private void prePareAidl() {
- Intent intent = new Intent();
- intent.setClassName("com.example.aidlservertest","com.example.aidlservertest.Service.PersonService");
- bindService(intent,MyServerConnection, Context.BIND_AUTO_CREATE);
- }
-
- /**
- * 方法说明:创建ServiceConnection
- * 日期:2020-09-09 17:15
- */
- private ServiceConnection MyServerConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- System.out.println("---客户端 建立服务链接; Thread: "+Thread.currentThread().getName());
- //初始化远程iBinder实例,将iBinder转成远程服务代理对象,也就是PersonManagerProxy类对象,并调用它的方法
- personManagerInterface = Stub.asInterface(iBinder);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName componentName) {
- System.out.println("---客户端 断开服务链接; Thread: "+Thread.currentThread().getName());
- }
- };
- }
将客户端的PersonManagerProxy、Proxy、Stub、PersonBean三个类,原封不动拷贝到服务端工程下,三个类所在目录也要同客户端一致;
- public class PersonService extends Service {
-
- private List<PersonBean> list = new ArrayList<>();
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- System.out.println("---服务端 onStartCommand; Thread: "+Thread.currentThread().getName());
- return super.onStartCommand(intent, flags, startId);
- }
-
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- System.out.println("---服务端 onBind; Thread: "+Thread.currentThread().getName());
- return mIBinder;
- }
-
- /**
- * 方法说明:
- * 日期:2020-09-09 11:26
- */
- private IBinder mIBinder = new Stub(){
- @Override
- public void addPerson(PersonBean personBean) throws RemoteException {
- if (personBean != null){
- list.add(personBean);
- }
- System.out.println("---服务端 addPerson; Thread: "+Thread.currentThread().getName()+", list: "+list);
- }
- @Override
- public void deletePerson(PersonBean personBean) throws RemoteException {
- list.remove(personBean);
- System.out.println("---服务端 deletePerson; Thread: "+Thread.currentThread().getName()+", list: "+list);
- }
- @Override
- public List<PersonBean> getPerson() throws RemoteException {
- System.out.println("---服务端 getPerson; Thread: "+Thread.currentThread().getName()+", list: "+list);
- return list;
- }
- };
- }
- public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- startService(new Intent(this, PersonService.class));
- }
- }
使用startService开启服务;
- <service android:name="com.example.aidlservertest.Service.PersonService"
- android:enabled="true"
- android:exported="true"/>
到此整个手动创建AIDL工程已经结束,测试的时候,需要先运行服务端,再运行客户端;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。