AIDL相关的重要类和接口
1.IInterface
2.IBinder
3.Binder
4.BinderProxy
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();
}
IBinder
/**
* Attempt to retrieve a local implementation of an interface
* for this Binder object. If null is returned, you will need
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor);
/**
* Perform a generic operation with the object.
*
* @param code The action to perform. This should
* be a number between {@link #FIRST_CALL_TRANSACTION} and
* {@link #LAST_CALL_TRANSACTION}.
* @param data Marshalled data to send to the target. Must not be null.
* If you are not sending any data, you must create an empty Parcel
* that is given here.
* @param reply Marshalled data to be received from the target. May be
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
*
* @return Returns the result from {@link Binder#onTransact}. A successful call
* generally returns true; false generally means the transaction code was not
* understood.
*/
public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
throws RemoteException;
/**
* Interface for receiving a callback when the process hosting an IBinder
* has gone away.
*
* @see #linkToDeath
*/
public interface DeathRecipient {
public void binderDied();
}
public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
throws RemoteException;
public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
Binder
private IInterface mOwner;
private String mDescriptor;
public class Binder implements IBinder {
...
public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
...
}
BinderProxy
/**
* Retrieve a local interface - always null in case of a proxy
*/
public IInterface queryLocalInterface(String descriptor) {
return null;
}
IMusicService.aidl 的定义
interface IMusicService {
void updateMusicList(in List<SongInfo> musicFileList);
void getPlayList(out List<SongInfo> musicFileList);
boolean play(int position);
boolean pause();
boolean stop();
}
void updateMusicList(in List<SongInfo> musicFileList);
void getPlayList(out List<SongInfo> musicFileList);中的in和out表示数据走向的方向标记。in表示走向Remote服务,out表示走向客户端。它们之间的细节差别表现:


IMusicService 的类结构
IMusicService 有一个抽象的子类Stub, Stub继承自Binder,实现了IMusicService接口。Stub里面定义了一个Proxy类,Stub.Proxy直接实现了IMusicService接口。
public interface IMusicService extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements com.chiang.chnplayer.aidl.IMusicService {
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
private static class Proxy implements com.chiang.chnplayer.aidl.IMusicService {
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
}
public static com.chiang.chnplayer.aidl.IMusicService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.chiang.chnplayer.aidl.IMusicService))) {
return ((com.chiang.chnplayer.aidl.IMusicService) iin);
}
return new com.chiang.chnplayer.aidl.IMusicService.Stub.Proxy(obj);
}
}
public void updateMusicList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) throws android.os.RemoteException;
public void getPlayList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) throws android.os.RemoteException;
public boolean play(int position) throws android.os.RemoteException;
public boolean pause() throws android.os.RemoteException;
public boolean stop() throws android.os.RemoteException;
}

IMusicService 的具体实现
public interface IMusicService extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.chiang.chnplayer.aidl.IMusicService {
private static final java.lang.String DESCRIPTOR = "com.chiang.chnplayer.aidl.IMusicService";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.chiang.chnplayer.aidl.IMusicService interface,
* generating a proxy if needed.
*/
public static com.chiang.chnplayer.aidl.IMusicService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.chiang.chnplayer.aidl.IMusicService))) {
return ((com.chiang.chnplayer.aidl.IMusicService) iin);
}
return new com.chiang.chnplayer.aidl.IMusicService.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_updateMusicList: {
//验证Binder标识
data.enforceInterface(DESCRIPTOR);
java.util.List<com.chiang.chnplayer.aidl.SongInfo> _arg0;
_arg0 = data.createTypedArrayList(com.chiang.chnplayer.aidl.SongInfo.CREATOR);
this.updateMusicList(_arg0);//这调用的是继承IMusicService.Stub后实现的方法
reply.writeNoException();
return true;
}
case TRANSACTION_getPlayList: {
data.enforceInterface(DESCRIPTOR);
java.util.List<com.chiang.chnplayer.aidl.SongInfo> _arg0;
_arg0 = new java.util.ArrayList<com.chiang.chnplayer.aidl.SongInfo>();
this.getPlayList(_arg0);
reply.writeNoException();
reply.writeTypedList(_arg0);
return true;
}
case TRANSACTION_play: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
boolean _result = this.play(_arg0);
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_pause: {
data.enforceInterface(DESCRIPTOR);
boolean _result = this.pause();
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_stop: {
data.enforceInterface(DESCRIPTOR);
boolean _result = this.stop();
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.chiang.chnplayer.aidl.IMusicService {
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 updateMusicList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) 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.writeTypedList(musicFileList);
mRemote.transact(Stub.TRANSACTION_updateMusicList, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void getPlayList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getPlayList, _data, _reply, 0);
_reply.readException();
_reply.readTypedList(musicFileList, com.chiang.chnplayer.aidl.SongInfo.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public boolean play(int position) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(position);
mRemote.transact(Stub.TRANSACTION_play, _data, _reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public boolean pause() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_pause, _data, _reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public boolean stop() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_updateMusicList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPlayList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_play = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_pause = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
}
public void updateMusicList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) throws android.os.RemoteException;
public void getPlayList(java.util.List<com.chiang.chnplayer.aidl.SongInfo> musicFileList) throws android.os.RemoteException;
public boolean play(int position) throws android.os.RemoteException;
public boolean pause() throws android.os.RemoteException;
public boolean stop() throws android.os.RemoteException;
}
data.enforceInterface(DESCRIPTOR);//验证Binder标识
IMusicService.Stub的实现类(这里是匿名实现类)
private IMusicService.Stub mBinder=new IMusicService.Stub() {
@Override
public boolean stop() throws RemoteException {
return mMusicPlayer.stop();
}
@Override
public void updateMusicList(List<SongInfo> musicFileList)
throws RemoteException {
mMusicPlayer.updateMusicList(musicFileList);
}
@Override
public boolean play(int position) throws RemoteException {
return mMusicPlayer.play(position);
}
@Override
public boolean pause() throws RemoteException {
return mMusicPlayer.pause();
}
@Override
public void getPlayList(List<SongInfo> musicFileList)
throws RemoteException {
List<SongInfo> tmp = mMusicPlayer.getFileList();
int count = tmp.size();
for(int i = 0; i < count; i++)
{
musicFileList.add(tmp.get(i));
}
}
};
ServiceConnection中onServiceConnected参数 IBinder service的来源?
class MServiceConnetion implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service){
mIMusicService=IMusicService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
关于在同一进程绑定Service和跨进程绑定Service后,ServiceConnection返回的IBinder对象和X.Stub.asInterface返回的对象。
private IPayService mIPayService;
class PayServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIPayService = IPayService.Stub.asInterface(service);
mIPayService.toString();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
public static com.fmtech.aidl_payservice.IPayService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.fmtech.aidl_payservice.IPayService))) {
return ((com.fmtech.aidl_payservice.IPayService) iin);
}
return new com.fmtech.aidl_payservice.IPayService.Stub.Proxy(obj);
}
public class PayService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new PayServiceStub();
}
private void pay(){
...
}
class PayServiceStub extends IPayService.Stub{
@Override
public void callMethodInService() throws RemoteException {
pay();
}
}
}
1.同一进程绑定Service
ServiceConnection#onServiceConnected返回的对象是PayService在onBind中直接返回的PayServiceStub实例;IPayService.Stub.asInterface方法返回的也是PayServiceStub实例。所以,当MainActivity中mIPayService调用callMethodInService时,直接调用的是Payservice中的callMethodInService方法。不需要走其他流程。

2.跨进程绑定Service
ServiceConnection#onServiceConnected返回的对象是BinderProxy实例;IPayService.Stub.asInterface方法返回的是IPayService.Stub.Proxy实例。所以,当MainActivity中mIPayService调用callMethodInService时流程如下:
-->IPayService.Stub.Proxy#callMethodInService()-->BinderProxy#transact()
BinderProxy#queryLocalInterface()
public IInterface queryLocalInterface(String descriptor) {
return null;
}
当onServiceConnected返回的对象是BinderProxy时,asInterface()方法中queryLocalInterface()返回的是null,所以asInterface()方法会返回*.Stub.Proxy
public static com.chiang.chnplayer.aidl.IMusicService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.chiang.chnplayer.aidl.IMusicService))) {
return ((com.chiang.chnplayer.aidl.IMusicService) iin);
}
return new com.chiang.chnplayer.aidl.IMusicService.Stub.Proxy(obj);
}
@Override
public void callMethodInService() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(IPayService.Stub.TRANSACTION_callMethodInService, _data, _reply, 0);//mRemote即是BinderProxy实例
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
...
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
BinderProxy.transact后会调用native方法,由native层进行处理;最后,再由native层回调IPayService.Stub.onTransact()方法,进而调用callMethodInService()方法。

为什么跨进程绑定Service时,ServiceConnection#onServiceConnected返回的对象是BinderProxy实例?
........