前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

「Binder机制」实例篇,超详细

qiguaw 2025-04-26 20:28:07 资源文章 5 ℃ 0 评论



这篇先来看实例,第二篇分析源码

一、创建工程,并且创建两个端

如图,在此工程中创建了两个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 机制源码吧

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表