Android进阶-Binder原理讲解

0、Binder是什么?

1)机制:是一种进程间通信机制;
2)驱动:是一个虚拟物理设备驱动:
3)应用层:是一个能发起通信的Java类;service -> new stub(继承自Binder)

1、Binder有什么优势?

多进程的使用及优势:虚拟机分配给各个进程的运行内存是有限制的,LMK也会优先回收对系统资源的占用多的进程。
1)突破进程内存限制,如图库占用内存过多;
2)功能稳定性:独立的通信进程包保持长连接稳定性;
3)规避系统内存泄露:独立的WebView进程阻隔内存泄漏导致的问题;
4)隔离风险:对于不稳定的功能放入独立进程,避免导致主进程崩溃;
在这里插入图片描述
进程间的通信机制:共享内存、socket、管道、消息队列
特点:
1)性能:需要拷贝一次:
2)特点:基于C/S(客户端/服务端)架构:
3)安全性:为每个APP分配UID同时支持实名和匿名,而共享内存依赖于上层协议
uid可以找到对应的service、防止恶意软件入侵手机。再service注册时 将uid传给binder
实名:注册的;匿名:

2、Binder是怎么做到一次拷贝(系统调用)的?

传统的ipc通信,线程之间的内存是可以共享的 但进程是内存隔离的
进程之间只能通过内核控件调用
在这里插入图片描述

内存映射-》
虚拟内存-》安卓开发所说的内存-》指针-》虚拟地址(一个虚拟的地址指向)
物理内存-》
在这里插入图片描述

所有进程的内核空间是共享一个物理内存的(地球仪和地球的关系)
用户空间和内核控件通过系统调用,而Binder相当于给用户空间和内核控件提供了一个共享区域进行内存映射 因此无需两次copy
Binder又google工程师处理数据 无需担心数据死锁

3、MMAP的原理讲解

在这里插入图片描述

memory mapping
把虚拟内存和指定的物理内存进行绑定,开辟一块空间 指向该虚拟内存 将内存指向指针
虚拟内存-》物理内存(Binder驱动(文件)提供)

4、Binder机制是如何跨进程的

在这里插入图片描述
在这里插入图片描述
startActivity会发生几次通信?==bind Service会发生几次跨进程通信?进行6次跨进程通信。
init pid=1 -> init.rc-》zygote-》fork system service
serviceManager(服务器表)-》见通信机制
在这里插入图片描述

5、描述AIDL生产的java类细节

public interface IBookManager extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.example.xushuzhan.aidltest.IBookManager {
        private static final java.lang.String DESCRIPTOR = "com.example.xushuzhan.aidltest.IBookManager";

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

        /**
         * Cast an IBinder object into an com.example.xushuzhan.aidltest.IBookManager interface,
         * generating a proxy if needed.
         */
        public static com.example.xushuzhan.aidltest.IBookManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.example.xushuzhan.aidltest.IBookManager))) {
                return ((com.example.xushuzhan.aidltest.IBookManager) iin);
            }
            return new com.example.xushuzhan.aidltest.IBookManager.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 {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_basicTypes: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    long _arg1;
                    _arg1 = data.readLong();
                    boolean _arg2;
                    _arg2 = (0 != data.readInt());
                    float _arg3;
                    _arg3 = data.readFloat();
                    double _arg4;
                    _arg4 = data.readDouble();
                    java.lang.String _arg5;
                    _arg5 = data.readString();
                    this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_getBook: {
                    data.enforceInterface(DESCRIPTOR);
                    com.example.xushuzhan.aidltest.BookBean _result = this.getBook();
                    reply.writeNoException();
                    if ((_result != null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    } else {
                        reply.writeInt(0);
                    }
                    return true;
                }
                case TRANSACTION_addBook: {
                    data.enforceInterface(DESCRIPTOR);
                    com.example.xushuzhan.aidltest.BookBean _arg0;
                    if ((0 != data.readInt())) {
                        _arg0 = com.example.xushuzhan.aidltest.BookBean.CREATOR.createFromParcel(data);
                    } else {
                        _arg0 = null;
                    }
                    this.addBook(_arg0);
                    reply.writeNoException();
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.example.xushuzhan.aidltest.IBookManager {
            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;
            }

            /**
             * Demonstrates some basic types that you can use as parameters
             * and return values in AIDL.
             */
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(anInt);
                    _data.writeLong(aLong);
                    _data.writeInt(((aBoolean) ? (1) : (0)));
                    _data.writeFloat(aFloat);
                    _data.writeDouble(aDouble);
                    _data.writeString(aString);
                    mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public com.example.xushuzhan.aidltest.BookBean getBook() throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                com.example.xushuzhan.aidltest.BookBean _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_getBook, _data, _reply, 0);
                    _reply.readException();
                    if ((0 != _reply.readInt())) {
                        _result = com.example.xushuzhan.aidltest.BookBean.CREATOR.createFromParcel(_reply);
                    } else {
                        _result = null;
                    }
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

            @Override
            public void addBook(com.example.xushuzhan.aidltest.BookBean book) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    if ((book != null)) {
                        _data.writeInt(1);
                        book.writeToParcel(_data, 0);
                    } else {
                        _data.writeInt(0);
                    }
                    mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
        }

        static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_getBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    }

    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;

    //定义返回书本的方法
    public com.example.xushuzhan.aidltest.BookBean getBook() throws android.os.RemoteException;

    //定义添加书本的方法,这里的 in 代表数据的流向是:客户端->服务端,服务端对数据的任何修改都不会影响到客户端
    public void addBook(com.example.xushuzhan.aidltest.BookBean book) throws android.os.RemoteException;
}

**onTransact(int code, Parcel data, Parcel reply, int flags):**这就是一个比较核心的方法了,它主要是用来执行远程调用的目标方法,执行完后把返回值写入reply中。这个方法是运行在服务端的Binder线程池中,客户端发起请求的时候,会通过系统底层封装后交给此方法来处理,如果返回false,那么客户端将请求失败(调用不到所请求的方法)。参数如下:
**code:**即AIDL接口中方法的唯一标识,通过它可以确定调用的是那个方法。
**data:**客户端远程调用方法的时候传过来的参数的值被封装进了这个data,需要就可以取出。
**reply:**当前方法的返回值会被封装进reply。
**flags:**只有0和1(FLAG_ONEWAY)两种取值,取0表示同步操作(默认),取1表示客户端单向操作,无需等待服务端响应。

6、四大组件底层通信机制

参考aidl和binder通信原理

7、为什么Intent不能传递大数据?==binder传递数据限制

同步传输最大限制1M-8k约等于512k 异步要除以2。binder mmap底层异步有底层的限制
在这里插入图片描述在这里插入图片描述

剩余可了解:binder的数据结构(4个红黑树)线程池的设计

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值