IBinder
. This class is an implementation of IBinder that provides standard local implementation of such an object.
IPC |
数据拷贝次数 |
共享内存 |
0 |
Binder |
1 |
Socket/管道/消息队列 |
2
|
package com.example.aidldemo;
interface IAidlCall{
String getName();
}
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: /Users/chenjiawei/Documents/AndroidSpace/ClientDemo/src/com/example/aidldemo/IAidlCall.aidl
*/
package com.example.aidldemo;
public interface IAidlCall extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.example.aidldemo.IAidlCall {
// Binder的唯一标示,一般用当前Binder的类名来标示
private static final java.lang.String DESCRIPTOR = "com.example.aidldemo.IAidlCall";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.aidldemo.IAidlCall
* interface, generating a proxy if needed.
*/
public static com.example.aidldemo.IAidlCall asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.aidldemo.IAidlCall))) {
return ((com.example.aidldemo.IAidlCall) iin);
}
return new com.example.aidldemo.IAidlCall.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_getName: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getName();
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.aidldemo.IAidlCall {
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 java.lang.String getName() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getName, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String getName() throws android.os.RemoteException;
}
/**
* 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();
}
public class MyServiceImpl extends IAidlCall.Stub {
@Override
public String getName() throws RemoteException {
return "Jack";
}
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
call = IAidlCall.Stub.asInterface(service);
try {
Toast.makeText(getApplicationContext(), call.getName(),
Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
/**
* Cast an IBinder object into an com.example.aidldemo.IAidlCall
* interface, generating a proxy if needed.
*/
public static com.example.aidldemo.IAidlCall asInterface(android.os.IBinder obj) {
//首先判断IBinder是否为空,因为Binder可以“死亡”,前面的有提过
if ((obj == null)) {
return null;
}
//这里queryLocalInterface方法得到IInterface对象,这是通过attachInterface赋值过去的
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
//如果iin不为空并且是IAidlCall实例则将其强转成IAidlCall对象并返回
if (((iin != null) && (iin instanceof com.example.aidldemo.IAidlCall))){
return ((com.example.aidldemo.IAidlCall) iin);
}
//如果lin为空或者不是IAidlCall实例,则返回Proxy对象
return new com.example.aidldemo.IAidlCall.Stub.Proxy(obj);
}
这里我们可以看到一个Proxy类,该类是Stub里的静态类且继承于
IAidlCall
,在Proxy类中有真正完成getName()方法实现的过程。实现getName方法的代码如下。
@Override
public java.lang.String getName() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getName, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
/**
* 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 (false) 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;
}
从该代码中我们可以看到调用了
onTransact方法,在该方法中会把远程方法返回值写入到
_reply
中。在
IAidlCall接口中的Stub类中,我们可以看到onTransact方法的实现,代码如下。 @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_getName: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getName();
reply.writeNoException();
// 这里将getName的返回值写入到reply中
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
至此,我们分析完了
IAidlCall接口类及其工作过程。其实我们也可以完全自己动手写出
IAidlCall.java,在《Android开发艺术探索》书中就有给出相应地例子。下面可以看看AIDL的工作图。