文章目錄
前言
上一篇文章講了AIDL的使用,我們知道AIDL是方便我們使用Binder的插件,那麼AIDL到底做了哪些事情呢?不知道你有沒有看過Activity的啓動流程,最終會跨進程調用ActivityManageService,但是他並沒有使用AIDL呀,他是怎麼使用Binder的呢?看完這篇文章你就知道了。
由於跨進程並不能直接傳遞對象,所以除了一些基本類型之外要傳遞的對象都需要先進行序列化操作,java中的序列化方式有兩種:Serializable和Parcelable,Parcelable的性能更好所以是安卓推薦的方式。
代碼結構分析
還記得上一篇文章寫好AIDL後會clean一下項目嗎,這一步操作是爲了生成一個文件IMyAidlInterface.java,這個接口就是Binder通信的真正執行者,看一下這個接口的結構:
這個接口中有三個方法:basicTypes、getPeople、addPeople。
都是我們在IMyAidlInterface.aidl中定義的通信方法,接口中有兩個內部類:Default和Stub,Default我們不用管,Stub這個名字熟悉嗎?這不就是我們在Service中定義和返回的binder嗎:
private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
Log.e(TAG, "basicTypes: anInt=" + anInt + " aLong=" + aLong + " aBoolean=" + aBoolean +
" aFloat=" + aFloat + " aDouble=" + aDouble + " aString=" + aString);
}
@Override
public People getPeople() throws RemoteException {
return people;
}
@Override
public void addPeople(People people) throws RemoteException {
Log.e(TAG, "addPeople: " + people.toString());
}
};
原來這個類是從這裏來的,另外Stub中還有一個內部類Proxy,這個類就這麼多東西,我們看一下他全部的代碼:
public interface IMyAidlInterface extends android.os.IInterface
{
/** Default implementation for IMyAidlInterface. */
public static class Default implements com.czy.server.IMyAidlInterface
{
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
{
}
@Override public com.czy.server.People getPeople() throws android.os.RemoteException
{
return null;
}
@Override public void addPeople(com.czy.server.People people) throws android.os.RemoteException
{
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.czy.server.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.czy.server.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.czy.server.IMyAidlInterface))) {
return ((com.czy.server.IMyAidlInterface)iin);
}
return new com.czy.server.IMyAidlInterface.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
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_basicTypes:
{
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0!=data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
return true;
}
case TRANSACTION_getPeople:
{
data.enforceInterface(descriptor);
com.czy.server.People _result = this.getPeople();
reply.writeNoException();
if ((_result!=null)) {
reply.writeInt(1);
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_addPeople:
{
data.enforceInterface(descriptor);
com.czy.server.People _arg0;
if ((0!=data.readInt())) {
_arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.addPeople(_arg0);
reply.writeNoException();
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.czy.server.IMyAidlInterface
{
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;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) 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(anInt);
_data.writeLong(aLong);
_data.writeInt(((aBoolean)?(1):(0)));
_data.writeFloat(aFloat);
_data.writeDouble(aDouble);
_data.writeString(aString);
boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
return;
}
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public com.czy.server.People getPeople() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
com.czy.server.People _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getPeople();
}
_reply.readException();
if ((0!=_reply.readInt())) {
_result = com.czy.server.People.CREATOR.createFromParcel(_reply);
}
else {
_result = null;
}
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public void addPeople(com.czy.server.People people) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((people!=null)) {
_data.writeInt(1);
people.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
boolean _status = mRemote.transact(Stub.TRANSACTION_addPeople, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().addPeople(people);
return;
}
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public static com.czy.server.IMyAidlInterface sDefaultImpl;
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
if (Stub.Proxy.sDefaultImpl == null && impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.czy.server.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
public com.czy.server.People getPeople() throws android.os.RemoteException;
public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
}
代碼分析
1.IMyAidlInterface
刪除其中的內部類單純看這個接口比較簡單:
public interface IMyAidlInterface extends android.os.IInterface {
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
public com.czy.server.People getPeople() throws android.os.RemoteException;
public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
}
這是一個繼承了IInterface的接口,裏面定義了進行通信的三個方法,這個接口沒有什麼實際的意義,主要是Stub和Proxy都實現它。
2.IMyAidlInterface.Stub
同樣刪除他的內部類Proxy來看他的代碼:
public static abstract class Stub extends android.os.Binder implements com.czy.server.IMyAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.czy.server.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.czy.server.IMyAidlInterface))) {
return ((com.czy.server.IMyAidlInterface) iin);
}
return new com.czy.server.IMyAidlInterface.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 {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_basicTypes: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0 != data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
return true;
}
case TRANSACTION_getPeople: {
data.enforceInterface(descriptor);
com.czy.server.People _result = this.getPeople();
reply.writeNoException();
if ((_result != null)) {
reply.writeInt(1);
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_addPeople: {
data.enforceInterface(descriptor);
com.czy.server.People _arg0;
if ((0 != data.readInt())) {
_arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.addPeople(_arg0);
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
if (Stub.Proxy.sDefaultImpl == null && impl != null) {
Stub.Proxy.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.czy.server.IMyAidlInterface getDefaultImpl() {
return Stub.Proxy.sDefaultImpl;
}
}
Stub繼承了Binder並實現了IMyAidlInterface,我們來一個個分析他的方法:
Stub()
首先他的構造函數調用了父類的attachInterface方法,並將本身和Stub的唯一標識DESCRIPTOR傳遞過,看一下這個方法:
public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
只是將傳遞的參數保存起來,兩個參數後面會用到。
asInterface
不知道大家還記不記得這是在連接遠程服務之後將Binder對象轉化爲IMyAidlInterface接口類型的方法:
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
看一下這個方法的具體內容:
public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.czy.server.IMyAidlInterface))) {
return ((com.czy.server.IMyAidlInterface) iin);
}
return new com.czy.server.IMyAidlInterface.Stub.Proxy(obj);
}
這裏根據參數不同會有兩種情況,如果服務端和客戶端在同一個進程就會返回iin,如果在不同進程就會new一個Proxy返回。
那麼怎麼判斷在不在一個進程呢,這就看queryLocalInterface方法了:
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor != null && mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
這裏用到了mDescriptor,還記得Stub的構造函數嗎,這是DESCRIPTOR的值,這裏就是判斷是不是同一個Stub,是就返回自己。
通過這個判斷我們可以知道IMyAidlInterface.Stub.asInterface(service)中的service和IMyAidlInterface.Stub是不是一個類,這只是一個類型判斷,但是這也不能區分在不在一個進程呀,後面還有一個判斷
(iin instanceof com.czy.server.IMyAidlInterface)
這還是類型判斷,確保轉換的對象是正確的,看來一開始的思路錯了,不賣關子了,其實同一個進程和不同進程傳遞中asInterface(android.os.IBinder obj)傳遞的參數是不一樣的,同一個進程是服務端返回的binder(IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub()),而不同進程是BinderProxy,這是爲什麼暫時不說,BinderProxy和Binder一樣實現了IBinder接口,看一下他的queryLocalInterface方法
public IInterface queryLocalInterface(String descriptor) {
return null;
}
這裏是百分百返回null,所以asInterface最後也就返回了Proxy。
asBinder
@Override
public android.os.IBinder asBinder() {
return this;
}
返回自己沒什麼說的。
TRANSACTION
Stub定義了很多TRANSACTION開頭的常量:
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
這個是用來在不同進程間標識一個方法的方式,跨進程的方法並不能直接調用,所以服務端收到消息後知道你調用那個方法,就是通過這個來標識的。
onTransact
到了最重要的方法了,這裏是調用服務端方法並返回的地方:
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_basicTypes: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0 != data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
return true;
}
case TRANSACTION_getPeople: {
data.enforceInterface(descriptor);
//調用自己的getPeople方法
com.czy.server.People _result = this.getPeople();
reply.writeNoException();
if ((_result != null)) {
reply.writeInt(1);
//將返回值寫入reply中
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_addPeople: {
data.enforceInterface(descriptor);
com.czy.server.People _arg0;
if ((0 != data.readInt())) {
//取出data中的參數
_arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
//調用自己的addPeople方法
this.addPeople(_arg0);
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
首先通過code也就是TRANSACTION判斷調用的那一個方法,比如TRANSACTION_getPeople,先是調用了自己的getPeople方法,也就是MyService中的getPeople方法,然後向reply中寫入返回值。
如果是有參數的方法,比如TRANSACTION_addPeople,會從data中取出參數,然後調用自己的addPeople方法並把參數傳入。
不知道你注意到了沒有,上面的取出參數和寫入返回值就是對象的序列化和反序列化。
3.IMyAidlInterface.Stub.Proxy
在不同的進程中asInterface會返回Proxy,那麼Proxy到底做了什麼呢?
private static class Proxy implements com.czy.server.IMyAidlInterface {
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;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) 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(anInt);
_data.writeLong(aLong);
_data.writeInt(((aBoolean) ? (1) : (0)));
_data.writeFloat(aFloat);
_data.writeDouble(aDouble);
_data.writeString(aString);
boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
return;
}
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public com.czy.server.People getPeople() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
com.czy.server.People _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getPeople();
}
_reply.readException();
if ((0 != _reply.readInt())) {
_result = com.czy.server.People.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public void addPeople(com.czy.server.People people) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((people != null)) {
_data.writeInt(1);
people.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
boolean _status = mRemote.transact(Stub.TRANSACTION_addPeople, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().addPeople(people);
return;
}
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public static com.czy.server.IMyAidlInterface sDefaultImpl;
}
Proxy也實現了IMyAidlInterface ,既然asInterface返回的是Proxy,那麼調用的getPeople和addPeople就是這裏面的方法了。
實際上Proxy裏也就只有這些方法。
getPeople
@Override
public com.czy.server.People getPeople() throws android.os.RemoteException {
//初始化參數Parcel
android.os.Parcel _data = android.os.Parcel.obtain();
//初始化返回值Parcel
android.os.Parcel _reply = android.os.Parcel.obtain();
com.czy.server.People _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//遠程調用方法
boolean _status = mRemote.transact(Stub.TRANSACTION_getPeople, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getPeople();
}
_reply.readException();
if ((0 != _reply.readInt())) {
//獲取返回值對象
_result = com.czy.server.People.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
首先初始化了參數和返回值Parcel,由於沒有參數所以_data中並沒有值,然後就去調用transact方法遠程調用getPeople,調用完成之後將_reply中的返回值反序列化,最後將反序列化後的返回值返回給調用方。
addPeople
和getPeople類似,只是沒有返回值就不看了。
到這裏整個IMyAidlInterface.java就講完了,Binder的應用層也就講完了,在往下就要牽扯到framework層了,基本上理解上面講的那麼多就夠日常使用了。爲了驗證你已經理解了我們還要做一件事情,就是把IMyAidlInterface.java這個文件拆分(其實上面分析的時候我已經把他拆開了),我們看到ActivityManageService並沒有Stub、Proxy這些就是因爲他沒有放到一起,而且Stub、Proxy這些名字也是可以隨意改的,我就不把過程寫出來了,直接把已經分離的代碼貼出來。
代碼分離
1.IMyAidlInterface
public interface IMyAidlInterface extends android.os.IInterface {
static final java.lang.String DESCRIPTOR = "com.czy.server.IMyAidlInterface";
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_addPeople = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
public com.czy.server.People getPeople() throws android.os.RemoteException;
public void addPeople(com.czy.server.People people) throws android.os.RemoteException;
}
2.IMyAidlInterfaceStubImpl
public abstract class IMyAidlInterfaceStubImpl extends android.os.Binder implements com.czy.server.IMyAidlInterface {
/**
* Construct the stub at attach it to the interface.
*/
public IMyAidlInterfaceStubImpl() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.czy.server.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.czy.server.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.czy.server.IMyAidlInterface))) {
return ((com.czy.server.IMyAidlInterface) iin);
}
return new IMyAidlInterfaceProxyImpl(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 {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_basicTypes: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
long _arg1;
_arg1 = data.readLong();
boolean _arg2;
_arg2 = (0 != data.readInt());
float _arg3;
_arg3 = data.readFloat();
double _arg4;
_arg4 = data.readDouble();
java.lang.String _arg5;
_arg5 = data.readString();
this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
reply.writeNoException();
return true;
}
case TRANSACTION_getPeople: {
data.enforceInterface(descriptor);
com.czy.server.People _result = this.getPeople();
reply.writeNoException();
if ((_result != null)) {
reply.writeInt(1);
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
case TRANSACTION_addPeople: {
data.enforceInterface(descriptor);
com.czy.server.People _arg0;
if ((0 != data.readInt())) {
_arg0 = com.czy.server.People.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.addPeople(_arg0);
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
public static boolean setDefaultImpl(com.czy.server.IMyAidlInterface impl) {
if (IMyAidlInterfaceProxyImpl.sDefaultImpl == null && impl != null) {
IMyAidlInterfaceProxyImpl.sDefaultImpl = impl;
return true;
}
return false;
}
public static com.czy.server.IMyAidlInterface getDefaultImpl() {
return IMyAidlInterfaceProxyImpl.sDefaultImpl;
}
}
3.IMyAidlInterfaceProxyImpl
public class IMyAidlInterfaceProxyImpl implements com.czy.server.IMyAidlInterface {
private android.os.IBinder mRemote;
IMyAidlInterfaceProxyImpl(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) 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(anInt);
_data.writeLong(aLong);
_data.writeInt(((aBoolean) ? (1) : (0)));
_data.writeFloat(aFloat);
_data.writeDouble(aDouble);
_data.writeString(aString);
boolean _status = mRemote.transact(TRANSACTION_basicTypes, _data, _reply, 0);
if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
IMyAidlInterfaceStubImpl.getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
return;
}
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public com.czy.server.People getPeople() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
com.czy.server.People _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
boolean _status = mRemote.transact(TRANSACTION_getPeople, _data, _reply, 0);
if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
return IMyAidlInterfaceStubImpl.getDefaultImpl().getPeople();
}
_reply.readException();
if ((0 != _reply.readInt())) {
_result = com.czy.server.People.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public void addPeople(com.czy.server.People people) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((people != null)) {
_data.writeInt(1);
people.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
boolean _status = mRemote.transact(TRANSACTION_addPeople, _data, _reply, 0);
if (!_status && IMyAidlInterfaceStubImpl.getDefaultImpl() != null) {
IMyAidlInterfaceStubImpl.getDefaultImpl().addPeople(people);
return;
}
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public static com.czy.server.IMyAidlInterface sDefaultImpl;
}
最後不要忘了把AIDL文件夾刪掉。