public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
int flags, String callingPackage, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeStrongBinder(token);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(connection.asBinder());
data.writeInt(flags);
data.writeString(callingPackage);
data.writeInt(userId);
// ccf: mRemote(BinderProxy)
// ccf: => BinderProxy#transact(...);
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
data.recycle();
reply.recycle();
return res;
}
Binder$BinderProxy.java
// 上一步中的mRemote即为BinderProxy对象!
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(); }
// ccf: => Binder#execTransact(...);
return transactNative(code, data, reply, flags);
}
Binder.java
(LoadedApk$ServiceDispatcher$InnerConnection)
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
try {
// ccf: => Binder$BinderProxy#BinderProxy(...);
// 绑定->创建Service的时候,code为1;此时会生成一个BinderProxy对象
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
// ...
res = true;
} catch (OutOfMemoryError e) {
// ...
res = true;
}
checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
reply.recycle();
data.recycle();
// Just in case -- we are done with the IPC, so there should be no more strict
// mode violations that have gathered for this thread. Either they have been
// parceled and are now in transport off to the caller, or we are returning back
// to the main transaction loop to wait for another incoming transaction. Either
// way, strict mode begone!
StrictMode.clearGatheredViolations();
return res;
}
Binder$BinderProxy.java
BinderProxy() {
mSelf = new WeakReference(this);
}
// 生成Binder中间驱动,onServiceConnected中的第二个参数,实际上就是该对象!
Activity.java # onServiceConnected
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.w(TAG, "onServiceConnected: " + service.hashCode() + " - " + Thread.currentThread().getName());
try {
// ccf: => Binder$BinderProxy#transact(...);
service.transact(101010, Parcel.obtain(), Parcel.obtain(), 0);
} catch (RemoteException e) {
}
}
// ...
}
Binder$BinderProxy.java
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);
}