您的位置:首页 > 移动开发 > Android开发

android service aidl 理解

2014-03-22 23:19 260 查看
参考:http://developer.android.com/guide/components/aidl.html

http://developer.android.com/guide/topics/manifest/service-element.html

service 属性基础

public interface ISecondary extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.example.android.apis.app.ISecondary {
private static final java.lang.String DESCRIPTOR = "com.example.android.apis.app.ISecondary";

/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}

/**
* Cast an IBinder object into an
* com.example.android.apis.app.ISecondary interface, generating a proxy
* if needed.
*/
public static com.example.android.apis.app.ISecondary asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface) obj
.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.android.apis.app.ISecondary))) {
return ((com.example.android.apis.app.ISecondary) iin);
}
return new com.example.android.apis.app.ISecondary.Stub.Proxy(obj);
}

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_getPid: {
data.enforceInterface(DESCRIPTOR);
int _result = this.getPid();
reply.writeNoException();
reply.writeInt(_result);
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;
}
}
return super.onTransact(code, data, reply, flags);
}

private static class Proxy implements
com.example.android.apis.app.ISecondary {
private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote) {
mRemote = remote;
}

public android.os.IBinder asBinder() {
return mRemote;
}

public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}

/**
* Request the PID of this service, to do evil things with it.
*/
public int getPid() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getPid, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

/**
* This demonstrates the 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 {
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);
mRemote.transact(Stub.TRANSACTION_basicTypes, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}

static final int TRANSACTION_getPid = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}

/**
* Request the PID of this service, to do evil things with it.
*/
public int getPid() throws android.os.RemoteException;

/**
* This demonstrates the 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;
}


View Code

分析:

类结构:

接口ISecondary{

  抽象类Stub 继承 Binder 实现 ISecondary{

    类Proxy 实现Isecondary{

   

    }

  }



在Activity SeviceConnect 调用 ISencond.stub.asInteface 接口获取ISencond实例 分析 asInteface方法:

public static com.example.android.apis.app.ISecondary asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface) obj
.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.android.apis.app.ISecondary))) {
return ((com.example.android.apis.app.ISecondary) iin);
}
return new com.example.android.apis.app.ISecondary.Stub.Proxy(obj);
}


查询是本地调用直接返回stub,如果是远程调用返回代理类Proxy。

至于以后调用如:mSecondaryService.getPid(),basicTypes等,本地调用直接返回实现stup抽象函数实现的方法体,远程调用看Proxy中的实现的函数。

1.将参数实例化Parcel(_data)对象,传递到Binder驱动。让客户端进程休眠,并且将传过来的pacel数据从客户端进程映射到服务端进程。

2.服务端线程调用ontransact方法解包执行相应方法操作并将返回值写入parcel(_reply)。

3.服务端线程将返回值传递给binder驱动,binder驱动重新唤醒客户端进程并把返回值传递给proxy对象,会被调用并最后被解包并作为proxy方法的返回值。

说明:

1.来自本地进程的调用会在与调用者相同的线程中被执行。如果这是主UI线程,那么线程会在AIDL接口中继续执行。如果是另外一个线程,那么调用例程是在服务中要执行代码之一。因此,只有正在访问服务的本地线程,才能够完全控制调用会在哪个线程中执行(但是,这个中情况下,完全不需要使用AIDL,而是应该通过实现Binder来创建接口)。

2.来自远程进程的调用会被分配到一个由平台维护的进程内部的线程池中。你必须为来自未知的、同时发生的多次调用的线程做好准备。换句话说,AIDL接口的实现必须是线程安全的。

3.oneway关键词是用来修饰远程调用行为的。当使用该关键词时,远程调用不是阻塞的,它只是发送事物数据并立即返回。接口的实现最终实现是把普通的远程调用按照Binder线程池的调用规则来接收的。如果oneway是使用在本地调用上,那么不会有任何影响,并且调用依然是同步的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: