android IPC

可以参考链接

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的本地引用。
     
     
调用传入的obj是 BinderProxy 代理对象

     return new android.os.IAutoBrightnessListener.Stub.Proxy(obj);
 代理的获取
     获取接口Ixxx=IxxxService.Stub.asInterface(Ibinder*)
     javaObjectForIBinder() 创建代理BinderProxy对象
     asInterface()将BinderProxy封装成IxxxService.Stub.Proxy
frameworks\base\core\jni\android_util_Binder.cpp 中 
javaObjectForIBinder()返回 BinderProxy 给到asInterface()为参数
04-10 09:34:41.163   889   889 D JavaBinder: objectForBinder 0x9aad3430: created new proxy 0x69 !
04-10 09:34:41.164   889   889 D JavaBinder: New DRL @ 0xa561f1f0
04-10 09:34:41.164   889   889 D JavaBinder: Now have 0 binder ops
     当调用某一个方法如 onAutoBrightnessChanged,
     in.onAutoBrightnessChanged 调用的是 Proxy 类方法:
     private static class Proxy implements android.os.IAutoBrightnessListener

调用对应的方法这个时候会创建JavaBinder ,再调用
  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  就调用到了 JNI Native 层了,调用transactNative  即调用native 层 android_os_BinderProxy_transact

android IPC



android_os_BinderProxy_transact 中会调用

status_t err = target->transact(code, *data, reply, flags);
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());


再调用到BpBinder 的 transact

再通过binder 驱动调用,这样就到了服务端
接着调用JavaBBbinder的Ontransact

再调用Binder.java 中Binder的 execTransact

再调用到实现了stub 的类的onTransact

再调用stub 类的 onTransact(如果有调用super.)

再调用到binder onTransact(如果有调用super.)

//再 到 Binder.java 中 Binder 的 transact

再调用具体方法


,如果实现 stub 的类没有覆写 Ontrasact 则调用 Binder.java 中 Ontransact

否则调用覆盖了的,即服务端Ontransact

比如:

public class ActivityManagerService extends IActivityManager.Stub
{

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)

}

调用AMS 的 onTransact


@Override
public List<IBinder> getAppTasks(String callingPackage) {
    Slog.e("wuyue","call getAppTasks",new Throwable("for throwalbe getAppTasks"));

android IPC




/**
 * 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