-
Notifications
You must be signed in to change notification settings - Fork 43
android binder
cheyiliu edited this page Sep 30, 2014
·
18 revisions
先来个类比:
A想联系B,于是他拿出手机拨号,电话公司获得A的请求并呼叫B的号码,B听到铃声并接通,电话公司通知A呼叫已经接通,A开始和B沟通。
工程狮翻译:
client想和service沟通,于是client拿出bindService来拨号,framework(具体是谁还没看代码TODO)获得client的请求并呼叫service,service收到onBind的铃声并接通(返回binder),framework通过onServiceConnected通知client已经接通,client和service开始通话。
bindService, request to bind the target the service
onBind, return the instance of IXXService.Stub which extends from IBinder
onServiceConnected(ComponentName name, IBinder service), got an IBinder and to get the proxy by IXXService.Stub.asInterface(service)
注: call sequence中onServiceConnected得到的ibinder和IXXService.Stub.asInterface(service)的返回值和client/service是否是同一进程有关联。
public interface IXXService extends android.os.IInterface{
// API define
public void API1(java.lang.String arg1, java.lang.String arg2, java.lang.String arg3)
throws android.os.RemoteException;
}
public static abstract class IXXService.Stub extends android.os.Binder implements IXXService{
private static final java.lang.String DESCRIPTOR = "your.package.IXXService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an
* your.package.IXXService
* interface, generating a proxy if needed.
*/
public static your.package.IXXService asInterface(
android.os.IBinder obj)
{
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof your.package.IXXService))) {
return ((your.package.IXXService) iin);
}
return new your.package.IXXService.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_API1: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
java.lang.String _arg2;
_arg2 = data.readString();
this.API1(_arg0, _arg1, _arg2);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
static final int TRANSACTION_API1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
private static class IXXService.Stub.Proxy implements IXXService
{
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 API1(java.lang.String arg1, java.lang.String arg2,
java.lang.String arg3) 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.writeString(arg1);
_data.writeString(arg2);
_data.writeString(arg3);
mRemote.transact(Stub.TRANSACTION_API1, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
- class hierarchy
- call sequence
- define API class IDemo: public IInterface
- impl class BpDemo: public BpInterface , remote()->transact(PUSH, data, &reply);
- impl class BnDemo: public BnInterface , onTransact(){ ... }
- register the service, defaultServiceManager()->addService(String16("Demo"), new Demo());
- client get sm->getService(String16("Demo"));
- call
https://github.com/cheyiliu/testBinder
https://github.com/cheyiliu/BinderDemo
http://blog.csdn.net/luoshengyang/article/details/6618363
https://thenewcircle.com/s/post/1340/Deep_Dive_Into_Binder_Presentation.htm#title-slide
http://www.cnblogs.com/samchen2009/p/3316001.html
why proxy has a binder VS the stub extends from the binder?
- java 层bindService是如何管理的
- native srviceManager是如何管理的
- binder 驱动
Just build something.