android IPC

来源:互联网 发布:大数据的看法 编辑:程序博客网 时间:2024/06/08 10:36

可以参考链接

http://mp.weixin.qq.com/s/vykL2oMsfp0ySG-2y9dgPg


linkTodeath 和 unlinkTodeath

介绍下Binder的两个很重要的方法 linkTodeath 和 unlinkTodeath,如果服务端的Binder连接断裂 (称之为 Binder 死亡),会导致我们远程调用失败。更为关键的时,如果我们不知道Binder的连接已经断裂,那么客户端的功能就会受到影响。为此我们可以给Binder设置一个死亡代理,当Binder死亡时,我们就会收到通知,这个时候我们就可以给Binder设置一个死亡代理,这个时候就可以重新发起连接请求从而恢复连接。

声明一个IBinder.DeathRecipient对象,IBinder.DeathRecipient是一个接口,其内部只有一个binderDied,我们需要实现这个方法,当binder死亡的时候,系统就会回调binderDied方法,然后我们就可以移除之前绑定的binder代理并重新绑定远程服务:

frameworks\base\core\java\android\os\IInterface.java

package android.os;/** * Base class for Binder interfaces.  When defining a new interface, * you must derive it from IInterface. */public interface IInterface{    /**     * Retrieve the Binder object associated with this interface.     * You must use this instead of a plain cast, so that proxy objects     * can return the correct result.     */    public IBinder asBinder();}

frameworks\base\core\java\android\os\IBinder.java

* Base interface for a remotable object, the core part of a lightweight* remote procedure call mechanism designed for high performance when* performing in-process and cross-process calls.  This* interface describes the abstract protocol for interacting with a* remotable object.  Do not implement this interface directly, instead* extend from {@link Binder}.* * <p>The key IBinder API is {@link #transact transact()} matched by* {@link Binder#onTransact Binder.onTransact()}.  These* methods allow you to send a call to an IBinder object and receive a* call coming in to a Binder object, respectively.  This transaction API* is synchronous, such that a call to {@link #transact transact()} does not* return until the target has returned from* {@link Binder#onTransact Binder.onTransact()}; this is the* expected behavior when calling an object that exists in the local* process, and the underlying inter-process communication (IPC) mechanism* ensures that these same semantics apply when going across processes.
public interface IBinder {
}

frameworks\base\core\java\android\os\Binder.java

* Base class for a remotable object, the core part of a lightweight* remote procedure call mechanism defined by {@link IBinder}.* This class is an implementation of IBinder that provides* standard local implementation of such an object.** <p>Most developers will not implement this class directly, instead using the* <a href="{@docRoot}guide/components/aidl.html">aidl</a> tool to describe the desired* interface, having it generate the appropriate Binder subclass.  You can,* however, derive directly from Binder to implement your own custom RPC* protocol or simply instantiate a raw Binder object directly to use as a* token that can be shared across processes.
public class Binder implements IBinder {
}

final class BinderProxy implements IBinder {    public native boolean pingBinder();    public native boolean isBinderAlive();
}



这里 BinderProxy 是binder 的代理对象。每一个Binder对象都会唯一关联一个BinderProxy对象。

Proxy的含义就是Client进程得到的Server端Binder对象的一个本地引用。



实现一个Binder :


IAutoBrightnessListener.aidl

package android.os;
interface IAutoBrightnessListener{   void onAutoBrightnessChanged(int autoBrightness);}


接口实现的注意点:

a)实现一个接口就是要实现该接口的所有的方法(抽象类除外)。
b)接口中的方法都是抽象的。
c)多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。


extends与implements的区别:

extends 是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口来实现,这样就用到了implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了



自动生成的 IAutoBrightnessListener.java

out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\src\core\java\android\os\IAutoBrightnessListener.java


package android.os;public interface IAutoBrightnessListener extends android.os.IInterface {    /**     * Local-side IPC implementation stub class.     */    public static abstract class Stub extends android.os.Binder implements android.os            .IAutoBrightnessListener {        private static final java.lang.String DESCRIPTOR = "android.os.IAutoBrightnessListener";                /**         * Construct the stub at attach it to the interface.         */        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }                /**         * Cast an IBinder object into an android.os.IAutoBrightnessListener interface,         * generating a proxy if needed.         */        public static android.os.IAutoBrightnessListener asInterface(android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            if (((iin != null) && (iin instanceof android.os.IAutoBrightnessListener))) {                return ((android.os.IAutoBrightnessListener) iin);            }            return new android.os.IAutoBrightnessListener.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_onAutoBrightnessChanged: {                    data.enforceInterface(DESCRIPTOR);                    int _arg0;                    _arg0 = data.readInt();                    this.onAutoBrightnessChanged(_arg0);                    reply.writeNoException();                    return true;                }            }            return super.onTransact(code, data, reply, flags);        }                private static class Proxy implements android.os.IAutoBrightnessListener {            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 void onAutoBrightnessChanged(int autoBrightness) 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(autoBrightness);                    mRemote.transact(Stub.TRANSACTION_onAutoBrightnessChanged, _data, _reply, 0);                    _reply.readException();                } finally {                    _reply.recycle();                    _data.recycle();                }            }        }                static final int TRANSACTION_onAutoBrightnessChanged = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);    }        public void onAutoBrightnessChanged(int autoBrightness) throws android.os.RemoteException;}


这里 IAutoBrightnessListener 继承IInterface, 由于Binder 已经实现了IBinder ,而Binder是用于通信的。

1、这里IAutoBrightnessListener 由一个内部类静态抽象类 Stub 与 AIDL文件中接口组成。

2、

public static abstract class Stub extends android.os.Binder implements android.os        .IAutoBrightnessListener {

这里要使用Binder技术,就需要一个binder对象,Stub 因此继承Binder , 并实际上没有实现 IAutoBrightnessListener ,所有是抽象类,这是由其继承者去实现。


asInterface () 如果在同一进程则为 IAutoBrightnessListener 本身,否则为远端 romote 服务端。 

* <p>The system maintains a pool of transaction threads in each process that* it runs in.  These threads are used to dispatch all* IPCs coming in from other processes.  For example, when an IPC is made from* process A to process B, the calling thread in A blocks in transact() as* it sends the transaction to process B.  The next available pool thread in* B receives the incoming transaction, calls Binder.onTransact() on the target* object, and replies with the result Parcel.  Upon receiving its result, the* thread in process A returns to allow its execution to continue.  In effect,* other processes appear to use as additional threads that you did not create* executing in your own process.


调用过程:

客户端获取:接口  

     IInterface in = IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME));
     由于客户端与 实现端 不在同一个进程,获取的Ibinder  是 ServiceManager.getService(BatteryStats.SERVICE_NAME),其实是代理对象BinderProxy。
        Client是无法拿到Server端的 IBatteryStats对象的,所以需要proxy 实现 IBatteryStats ,作为 IBatteryStats的本地引用。
     
     调用传入的是 BinderProxy 代理对象
     return new android.os.IAutoBrightnessListener.Stub.Proxy(obj);
     
     当调用某一个方法如 onAutoBrightnessChanged,
     in.onAutoBrightnessChanged 调用的是 Proxy 类方法:
     private static class Proxy implements android.os.IAutoBrightnessListener
     即调用  mRemote.transact(Stub.TRANSACTION_onAutoBrightnessChanged, _data, _reply, 0);
    
     即调用   frameworks\base\core\java\android\os\Binder.java  中BinderProxy 的 transact
     
     
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {    Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");    if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }    return transactNative(code, data, reply, flags);}
transactNative  就调用到了 Native 层了,再通过binder 驱动调用到  Binder.java 中  Binder 的 transact
/** * Default implementation rewinds the parcels and calls onTransact.  On * the remote side, transact calls into the binder to do the IPC. */
public final boolean transact(int code, Parcel data, Parcel reply,        int flags) throws RemoteException {    if (true) Log.v("Binder", "Transact: " + code + " to " + this);    if (data != null) {        data.setDataPosition(0);    }    boolean r = onTransact(code, data, reply, flags);    if (reply != null) {        reply.setDataPosition(0);    }    return r;}

     这里继续调用 Binder.java 中
onTransact(code, data, reply, flags)
     
/** * Default implementation is a stub that returns false.  You will want * to override this to do the appropriate unmarshalling of transactions. * * <p>If you want to call this, call transact(). */protected boolean onTransact(int code, Parcel data, Parcel reply,        int flags) throws RemoteException {    if (code == INTERFACE_TRANSACTION) {        reply.writeString(getInterfaceDescriptor());        return true;    } else if (code == DUMP_TRANSACTION) {        ParcelFileDescriptor fd = data.readFileDescriptor();

 。。。

}


   这里由于服务端override  onTransact 方法,所以调用的是服务端实现了 stub 类的类的方法:

public final class BatteryConsumeService extends IBatteryConsume.Stub{
   onAutoBrightnessChanged(){
    。。。。
  }
}


   即调用的是  BatteryConsumeService 的 onAutoBrightnessChanged 方法。




如果调用者与服务端再同一个进程,那就不经过BinderProxy 了。



https://www.cnblogs.com/everhad/p/6246551.html




frameworks\native\include\binder\IBinder.h

class IBinder : public virtual RefBase
{


virtual BBinder*        localBinder();virtual BpBinder*       remoteBinder();

}



frameworks\native\include\binder\Binder.h

class BBinder : public IBinder
{

virtual status_t    transact(   uint32_t code,                                const Parcel& data,                                Parcel* reply,                                uint32_t flags = 0);
virtual status_t    onTransact( uint32_t code,                                const Parcel& data,                                Parcel* reply,                                uint32_t flags = 0);

virtual BBinder*    localBinder();
}

class BpRefBase : public virtual RefBase
{

inline  IBinder*        remote()                { return mRemote; }

IBinder* const          mRemote;RefBase::weakref_type*  mRefs;std::atomic<int32_t>    mState;

}



frameworks\native\include\binder\BpBinder.h

class BpBinder : public IBinder

{

virtual status_t    transact(   uint32_t code,                                const Parcel& data,                                Parcel* reply,                                uint32_t flags = 0);
virtual BpBinder*   remoteBinder();
                    BpBinder(int32_t handle);inline  int32_t     handle() const { return mHandle; }

const   int32_t             mHandle;

}



frameworks\native\include\binder\IInterface.h

class IInterface : public virtual RefBase{public:            IInterface();            static sp<IBinder>  asBinder(const IInterface*);            static sp<IBinder>  asBinder(const sp<IInterface>&);protected:    virtual                     ~IInterface();    virtual IBinder*            onAsBinder() = 0;};

template<typename INTERFACE>class BnInterface : public INTERFACE, public BBinder{public:    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);    virtual const String16&     getInterfaceDescriptor() const;protected:    virtual IBinder*            onAsBinder();};// ----------------------------------------------------------------------template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public:                                BpInterface(const sp<IBinder>& remote);protected:    virtual IBinder*            onAsBinder();};


这里BnInterface 

BpInterface 


frameworks\native\include\binder\IPCThreadState.h

class IPCThreadState{public:

}

frameworks\native\include\binder\ProcessState.h

class ProcessState : public virtual RefBase
{

}


mmap

https://www.cnblogs.com/huxiao-tee/p/4660352.html#_label5



原创粉丝点击