androidframework实战开发-binder专题讲解之aidl文件的详细分析(代码片段)

Android高级知识分享官 Android高级知识分享官     2023-01-10     786

关键词:

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论

android跨进程通信实战视频课程(加群获取优惠)

大家平时做应用开发时候也经常会遇到有跨进程通信的需求,这里大部分通信可能就会回答,就是用aidl,service。确实这个aidl和service的方式是应用开发中对binder接触层面应该属于最为接近的一层。因为其他的接口方式跨进程通信,比如startActivtiy,ContentProvider,broadcast,这些都是系统组件接口直接帮我们做好的,连binder的影子都看不见,自然也就对binder相对比较陌生。
本节就来重点介绍一下深入讲解分析应用层面binder通信的方式及原理,这一部分属于binder讲解的中级部分,这节课来讲解一下binder的aidl生成java文件的源码分析:
为什么要AIDL,它存在意义是?
在使用binder service进行跨进程通信经常我们会写aidl,那首先大家肯定会有疑问,那aidl到底是什么?AIDL是一个缩写,全称是Android Interface Definition Language,也就是Android接口定义语言。所以说aidl他只是一个语言,主要目的就是来帮助binder跨进程通信的接口定义而设计的一个语言,后缀是 .aidl结尾,他有自己的语法,不过基本和java比较类似,最后会通过一个aidl.exe把整个aidl文件都转换成对应的java文件,因为编译接口啥事我们java程序在使用当然要变成java 修改类文件,那这里同学肯定会说为什么不直接用java,还要搞个新语言,其实这里就问到了最关键的部分。
这里有以下原因:
1、如果要java语言实现那会导致要写很多重复的固定代码,写的代码量比较大,稍微不小心容易出错
2、这一部分完全可以让脚本根据某些配置文件来生成对应的java代码,而这个配置文件的正类似我们今天看到的aidl
本质如下图所示:

这里我们来按照上图来一步步实现:
1、明确哪个是客户端,哪个是服务
首先应用层跨进程通信时候,我们都一般会定义一个Service,因为Android中Service组件是可以运行于独立的进程即Service代码可能是在某一个apk下面,但是它运行的进程却不是这个apk的包名对应的进程,所以一般演示跨进程通信完全可以一个apk实现,这个Service就是我们真正的服务端,也是真正的业务实现端,客户端就是调用这个Service发起端,这个具体是在Activity中实现还是Service一般都是可以,一般我们为了方便就在Activity中进行跨进程通信的调用,即Activity作为客户端。
2、确定通信过程中的接口(即通信要获取的信息)
这个就是所说的aidl文件,它来定义好对应的通信接口接口,比如这里我们定义一个学生信息获取接口:
IStudentInterface .aidl

interface IStudentInterface 
    int getStudentId(String name);//定义一个根据学生名字查询学号的接口

aidl文件的转换
这个aidl文件写好后,点击make编译一下工程,在编译过程就会被aidl.exe转成对应的java文件,具体查看这个java文件,可以在android studio点击如下路径:

如果想要直接使用aidl.exe来命令生成也是完全可以
先到安卓sdk\\build-tools\\29.0.2下有aidl.exe

aidl.exe -IF:\\binder_drivers_code\\ServiceDemo\\app\\src\\main\\aidl\\com\\example\\servicedemo  F:\\binder_drivers_code\\ServiceDemo\\app\\src\\main\\aidl\\com\\example\\servicedemo\\IStudentInterface.aidl

"-I"与"F:\\binder_drivers_code***"之间是没有空格的,最后就会在F:\\binder_drivers_code\\ServiceDemo\\app\\src\\main\\aidl\\com\\example\\servicedemo生成一个IStudentInterface.java

这里相信大家已经明白了aidl是怎么一回事,它的本质目的就是为了帮助我们减少编写那些重复不变化的通信协议代码,这个完全可以让机器根据我们的描述配置文件来生成,这个描述配置文件其实就是我们的aidl文件

3、那我们已经生成了这个java文件,那我这个java文件到底内容是什么呢?
其实上面的图也提前展示了,它主要分别一部分是Stub 类和Stub .Proxy类

  public static abstract class Stub extends android.os.Binder implements com.example.servicedemo.IStudentInterface1
  
       。。省略
    public static com.example.servicedemo.IStudentInterface1 asInterface(android.os.IBinder obj)
    
         。。省略
      return new com.example.servicedemo.IStudentInterface1.Stub.Proxy(obj);
    
    @Override public android.os.IBinder asBinder()
    
      return this;
    
    //服务端,这个时候服务端驱动获取数据后,一系列调用会回调到onTransact
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    
      java.lang.String descriptor = DESCRIPTOR;
      switch (code)
      
           。。省略
        case TRANSACTION_getStudentId:
        
          data.enforceInterface(descriptor);
          java.lang.String _arg0;
          _arg0 = data.readString();
          int _result = this.getStudentId(_arg0);//这个地方就会真正调用Service中实现的那个getStudentId方法
          reply.writeNoException();
          reply.writeInt(_result);
          return true;
        
            。。省略
      
    
    private static class Proxy implements com.example.servicedemo.IStudentInterface1
    
     。。省略
      @Override public int getStudentId(java.lang.String name) throws android.os.RemoteException
      
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int _result;
        try 
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(name);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getStudentId, _data, _reply, 0);//客户端调用getStudent最后是通过mRemote调用到远程,并等待获取结果
          if (!_status && getDefaultImpl() != null) 
            return getDefaultImpl().getStudentId(name);
          
          _reply.readException();
          _result = _reply.readInt();
        
        finally 
          _reply.recycle();
          _data.recycle();
        
        return _result;
      
      public static com.example.servicedemo.IStudentInterface1 sDefaultImpl;
    
       。。省略
  

这里Stub就是远程端的具体真实实现,一般在服务端Serivce中实现,而Stub.Proxy类则是主要给客户端提供调用远程端的接口。对应的实际使用Stub类和Stub.Proxy类如下截图:
Stub的服务端实现截图:

Stub.Proxy的具体使用调用过程:

这里的asInterface上面代码也展示,其实就是
new com.example.servicedemo.IStudentInterface1.Stub.Proxy(obj);构造了一个Stub.Proxy本地对象。
最后总结一下aidl转成java文件后看到的一个跨进程调用的图:

androidframework实战开发视频--跨进程通信之unixsocket通信(代码片段)

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发视频–跨进程通信之UnixSocket1专门用于跨进程通信的UnixSocket做过java相关app开发肯定学过socket通信等一些小程序来实现局 查看详情

千里马androidframework实战开发-native程序之间binder通信实战案例分析(代码片段)

...进程通信实战视频课程(加群获取优惠)千里马AndroidFramework实战开发-native程序之间binder通信实战案例分析1、需求背景在android系统开发中,不仅仅我们都停留在java层面ÿ 查看详情

千里马androidframework实战开发-native程序之间binder通信实战案例分析(代码片段)

...进程通信实战视频课程(加群获取优惠)千里马AndroidFramework实战开发-native程序之间binder通信实战案例分析1、需求背景在android系统开发中,不仅仅我们都停留在java层面ÿ 查看详情

androidframework实战开发-socket让app实现shell命令行执行

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发-Socket让app实现shell命令行执行1、项目背景在android系统开发过程中,经常会有这样一个需求,就是可能需 查看详情

androidframework实战开发-socket让app实现shell命令行执行

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发-Socket让app实现shell命令行执行1、项目背景在android系统开发过程中,经常会有这样一个需求,就是可能需 查看详情

androidframework实战开发视频--跨进程通信之socket通信(代码片段)

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发视频–跨进程通信之Socket通信1Socket是什么呢?Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它 查看详情

androidframework实战开发视频--跨进程通信之socket通信(代码片段)

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发视频–跨进程通信之Socket通信1Socket是什么呢?Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它 查看详情

千里马androidframework实战开发-跨进程通信专题课表介绍

千里马AndroidFramework实战开发-跨进程通信专题课表介绍因为课程还剩下最后一部分binder驱动没有讲完,但是粉丝同学们已经迫不及待想要要提前看,这里就先分享一个课表给大家,提醒一下,课表的很大,你忍... 查看详情

androidframework实战开发视频--跨进程通信之unixsocket通信(代码片段)

AndroidFramework实战开发视频–跨进程通信之UnixSocket1专门用于跨进程通信的UnixSocket做过java相关app开发肯定学过socket通信等一些小程序来实现局域网通信,学会了通过ip地址来进行一种网络通信,但这种通信一般用于跨设备... 查看详情

androidframework实战开发-socketpair介绍及它在android系统源码使用分析(代码片段)

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发-socketpair介绍及它在android系统源码使用分析1.socketpair介绍在linux下,使用socketpair函数能 查看详情

androidframework实战开发-socketpair介绍及它在android系统源码使用分析(代码片段)

...android跨进程通信实战视频课程(加群获取优惠)AndroidFramework实战开发-socketpair介绍及它在android系统源码使用分析1.socketpair介绍在linux下,使用socketpair函数能 查看详情

androidframework实战开发-binder通信常见使用方式,及案例分析

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论android跨进程通信实战视频课程(加群获取优惠)(1)binder通信常见使用方式,及案例分析 查看详情

androidframework实战开发-binder通信常见使用方式,及案例分析

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论android跨进程通信实战视频课程(加群获取优惠)(1)binder通信常见使用方式,及案例分析 查看详情

千里马androidframework实战开发-binder驱动之oneway导致的transactionfailed(代码片段)

...进程通信实战视频课程(加群获取优惠)千里马androidframework实战开发-binder驱动之oneway导致的transactionfailed首先来看错误:06-1512:10:36.68631395 查看详情

千里马androidframework实战开发-binder驱动之oneway导致的transactionfailed(代码片段)

...进程通信实战视频课程(加群获取优惠)千里马androidframework实战开发-binder驱动之oneway导致的transactionfailed首先来看错误:06-1512:10:36.68631395 查看详情

千里马androidframework实战开发-跨进程通信专题博客总结

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论FrameWork入门课视频链接:https://edu.csdn.net/course/detail/30298FrameWork实战课1视频链接:https://edu.csdn.net/course/detail/30275androi 查看详情

千里马androidframework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战

...进程通信实战视频课程(加群获取优惠)千里马AndroidFramework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战背景:大家如果看到binder通信native和jav 查看详情

千里马androidframework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战(代码片段)

...进程通信实战视频课程(加群获取优惠)千里马AndroidFramework实战开发-am命令怎么编译生成及native程序与java程序的binder通信实战背景:大家如果看到binder通信native和jav 查看详情