zoukankan      html  css  js  c++  java
  • AIDL 的工作原理

    当创建AIDL文件并Clean Project 代码后,会生成相应的Java文件:

    先来一段伪代码:类整体结构

    /*
    * This file is auto-generated. DO NOT MODIFY.
    * Original file: D:\AndroidProject\AIDLServerDemo\app\src\main\aidl\cn\zzw\aidl\IPerson.aidl
    */
    package cn.zzw.aidl;
    // Declare any non-default types here with import statements

    public interface IPerson extends android.os.IInterface {
    /**
    * Local-side IPC implementation stub class.
    */
    public static abstract class Stub extends android.os.Binder implements cn.zzw.aidl.IPerson //1
    {
    ...
    }

    public java.lang.String sayHello(cn.zzw.aidl.PersonInfo personInfo) throws android.os.RemoteException; //2

    public int sumnNum(int num1, int num2) throws android.os.RemoteException; //3
    }
    注释2 和注释3 就是我们在.aidl 中定义的方法。

    注释1 是一个静态的抽象类,并且继承了Binder类。Binder是Android中实现IPC方式。AIDL就是利用Binder来实现的。

    这里就不对于Binder进行解释,后面会对Binder的源码进行解读,再记录一篇关于Binder的原理。

    看看Stub这个类:

    public static abstract class Stub extends android.os.Binder implements cn.zzw.aidl.IPerson {
    private static final java.lang.String DESCRIPTOR = "cn.zzw.aidl.IPerson";

    /**
    * Construct the stub at attach it to the interface.
    */
    public Stub() {
    this.attachInterface(this, DESCRIPTOR);
    }

    /**
    * Cast an IBinder object into an cn.zzw.aidl.IPerson interface,
    * generating a proxy if needed.
    */
    public static cn.zzw.aidl.IPerson asInterface(android.os.IBinder obj) {
    if ((obj == null)) {
    return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin != null) && (iin instanceof cn.zzw.aidl.IPerson))) {
    return ((cn.zzw.aidl.IPerson) iin);
    }
    return new cn.zzw.aidl.IPerson.Stub.Proxy(obj);
    }

    @Override
    public android.os.IBinder asBinder() {
    return this;
    }

    @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 INTERFACE_TRANSACTION: {
    reply.writeString(descriptor);
    return true;
    }
    case TRANSACTION_sayHello: {
    data.enforceInterface(descriptor);
    cn.zzw.aidl.PersonInfo _arg0;
    if ((0 != data.readInt())) {
    _arg0 = cn.zzw.aidl.PersonInfo.CREATOR.createFromParcel(data);
    } else {
    _arg0 = null;
    }
    java.lang.String _result = this.sayHello(_arg0);
    reply.writeNoException();
    reply.writeString(_result);
    return true;
    }
    case TRANSACTION_sumnNum: {
    data.enforceInterface(descriptor);
    int _arg0;
    _arg0 = data.readInt();
    int _arg1;
    _arg1 = data.readInt();
    int _result = this.sumnNum(_arg0, _arg1);
    reply.writeNoException();
    reply.writeInt(_result);
    return true;
    }
    default: {
    return super.onTransact(code, data, reply, flags);
    }
    }
    }

    private static class Proxy implements cn.zzw.aidl.IPerson {
    private android.os.IBinder mRemote;

    Proxy(android.os.IBinder remote) {
    mRemote = remote;
    }

    @Override
    public android.os.IBinder asBinder() {
    return mRemote;
    }

    public java.lang.String getInterfaceDescriptor() {
    return DESCRIPTOR;
    }

    @Override
    public java.lang.String sayHello(cn.zzw.aidl.PersonInfo personInfo) throws android.os.RemoteException {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    java.lang.String _result;
    try {
    _data.writeInterfaceToken(DESCRIPTOR);
    if ((personInfo != null)) {
    _data.writeInt(1);
    personInfo.writeToParcel(_data, 0);
    } else {
    _data.writeInt(0);
    }
    mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);
    _reply.readException();
    _result = _reply.readString();
    } finally {
    _reply.recycle();
    _data.recycle();
    }
    return _result;
    }

    @Override
    public int sumnNum(int num1, int num2) 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.writeInt(num1);
    _data.writeInt(num2);
    mRemote.transact(Stub.TRANSACTION_sumnNum, _data, _reply, 0);
    _reply.readException();
    _result = _reply.readInt();
    } finally {
    _reply.recycle();
    _data.recycle();
    }
    return _result;
    }
    }

    static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_sumnNum = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }
    Stub类的类结构如下:

    下面两个int常量是用来标识我们在接口中定义的方法的:

    static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_sumnNum = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    DESCRIPTOR 常量是Binder的唯一标识。

    private static final java.lang.String DESCRIPTOR = "cn.zzw.aidl.IPerson";
     asInterface 方法非常熟悉,上面客户端才用到的,用于将服务端的Binder对象转换为客户端所需要的接口对象。该过程区分进程,如果进程一样,就返回服务端Stub对象本身,否则就返回封装后的Stub.Proxy对象。

    public static cn.zzw.aidl.IPerson asInterface(android.os.IBinder obj) {
    if ((obj == null)) {
    return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin != null) && (iin instanceof cn.zzw.aidl.IPerson))) {
    return ((cn.zzw.aidl.IPerson) iin);
    }
    return new cn.zzw.aidl.IPerson.Stub.Proxy(obj);
    }
    onTransact  方法是实现 Binder 类后重写的方法。这是运行在服务端的Binder线程中的,当客户端发起远程请求后,在底层的方法就会触发此方法。

  • 相关阅读:
    GATK-BWA-MEM handle GRCh38 alternate contig mappings
    GATK使用说明-GRCh38(Genome Reference Consortium)(二)
    GATK使用说明(一)
    [python] 线程池
    [python] 线程锁
    [python] 线程简介
    [linux] 更改目录显示颜色
    限制登录次数
    项目经验总结-twice
    Java泛型底层源码解析--ConcurrentHashMap(JDK1.6/JDK1.7/JDK1.8)
  • 原文地址:https://www.cnblogs.com/ly570/p/11513080.html
Copyright © 2011-2022 走看看