这篇先来看实例,第二篇分析源码
一、创建工程,并且创建两个端
如图,在此工程中创建了两个module
black_client
black_server
二、在 black_server 端我们先创建 Aidl 文件
创建即可
然后在创建出来的 aidl 文件中定义我们想要给 server 端设置的方法
第三步、定义 aidl 拥有的功能
本例想让 server 端拥有 添加学生、获得学生列表 的方法。
① 那么首先我们需要先定义一个学生类
注意,因为我们需要在aidl 中使用此类,所以此类必须要实现 Parcelable 接口,这样才能跨进程使用此类。
② 有了上述中的学生类后,我们就可以定义 aidl 拥有的功能了
首先,在创建 aidl 文件生成的目录中,我们需要再创建一个与学生类对应的 aidl 文件,如下图
这样定义后,IMyAidlInterface.aidl 文件才能关联上学生类,并且能够 make成功。
然后我们再定义 aidl 拥有的功能,如下图
需要说明的是 addStudent(in Student student)方法的定义,in 表示是输入的参数,必须指定。
此外,还要手动 import Student 的包,否则在 make 的时候会无法找到Student 类。
这样我们就定义完了 aidl 文件拥有的功能了。
③ make project
make成功后,就生成了能让客户端远程访问的桥梁。
桥梁搭好了,但是具体 aidl 的功能的实现还没有做,下一步就要让服务端完成这些功能的实现。
Stub 抽象类即是我们 server 端要实现的类,即具体的 aidl 的功能需要 server 端实现 aidl 中的 Stub 抽象类才能具体化。
第四步、我们继续完成服务端的逻辑
在服务端创建 ServerService 文件
然后创建内部类,实现 aidl 中的 Stub抽象类
实现这两个方法,下图具体实现:
最后,清单文件中注册此 Service。
注意:一定要将
android:exported="true"
加上,这样才能被其他进程调用。
这样,我们就把服务端的逻辑处理完了
第五步、配置客户端
① 将服务端的 Person 类复制过来,注意包名需要与服务端完全相同
② 给客户端添加两个按钮,一个按钮触发 bindService 事件,一个按钮用来操作服务端进程的逻辑。
自定义了两个方法 bindService 和 handle 方法。
我们先把绑定服务的代码完善下:
bindService 写完后,别忘了在 Activity 销毁的时候,调用 unBindService 方法
当 service 连接成功后,需要通过 service 获取到 服务端的代理,进而再访问到服务端实际逻辑。
所以此时,我们需要把服务端的 aidl 的代码完全复制过来(包名一致),然后再 make project,才能够使用 aidl 。
③ 复制 aidl 文件夹,并且 make project
复制完后,make
④ 客户端 make 完后,就可以继续完善上面的两个方法了
//通过此方法,我们会拿到服务端的代理IMyAidlInterface.Stub.asInterface(service)
//通过代理调用服务端的方法,具体内部的实现是服务端实现iMyAidlInterface.addStudent()iMyAidlInterface.getStudents()
第六步、运行
先跑服务端,再跑客服端,否则客户端会因为找不到对应的 service 而报错。
先点击 “绑定服务端”,再点击几次 “操作远程 service 的逻辑”
打印结果为
说明我们已经从客户端通过 aidl 访问到了 服务端提供的逻辑。
此时我们杀死服务端程序,这个时候,客户端与服务端的连接会断开
此时,再次点击 “绑定服务端”
发现,仍然是可以绑定的。
再次点击 “操作远程 service 的逻辑”
仍然可以操作。
说明客户端想要远程访问服务端,只需要服务端在手机上存在即可,不需要提前开启服务端。
至此,我们的例子就介绍完了。
最后,我们来从客户端正向理一下 aidl 的调用过程。
//获得 AIDL 的代理 ProxyIMyAidlInterface.Stub.asInterface(service);
//调用 Proxy 的 addStudent 方法iMyAidlInterface.addStudent();
这里有两个 Parcel 文件,一个 _data 一个 _reply,data 表示的是调用服务端传入的数据,而 reply 表示的是服务端返回给客户端的数据。
//Proxy 内部调用 Binder 的 transact 方法mRomote.transact(Stub.TRANSACTION_addStudent,_data,_reply,0)
进而调用 Binder 的 onTransact()方法
//而 AIDL 文件中的 Stub 是 Binder 的子类,它实现了 Binder 的 onTransact() 方法。Stub.onTransact()
最终会来到
this.addStudent()
这个 addStudent() 只有服务端的 Service 内部类实现了
所以最终会调用到服务端的处理逻辑。
画个时序图,大概是这样的
今天就到这,下篇一起看下 binder 机制源码吧
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/53702.html