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_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"));
/** * 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