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

Android 使用AIDL实现进程之间的通信(一)

2016-11-24 12:56 661 查看
下面开始介绍下Android 之间进程之间的通信方式,AIDL是Android之间进程通信的方式之一,底层依然使用的是Binder,随后会介绍Binder的实现原理

创建AIDL文件

在AndroidStudio 中创建AIDL文件,会自动创建AIDL目录,在工程中与Java目录平级

// IMyAidl.aidl
package cn.edu.hebust.aidldemo;

// Declare any non-default types here with import statements

interface IMyAidl {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
* AIDL 通信的基本数据类型
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);

// 提供给其他客户端的接口方法
int add(int num1, int num2);
}


ctrl+b 进行编译,或者是用SDKtool提供的工具,将AIDL文件编译成.java文件

生成的java文件在

~/app/build/generated/source/aidl/debug/cn/edu/hebust/aidldemo



这个文件不需要我们更改,但是理解以后对我们了解Binder还是很有帮助的

/*
* This file is auto-generated.  DO NOT MODIFY.
* Original file: /media/yangtianrui/system/AndroidProject/AndroidStudioProjects/AIDLDemo/app/src/main/aidl/cn/edu/hebust/aidldemo/IMyAidl.aidl
*/
package cn.edu.hebust.aidldemo;
// Declare any non-default types here with import statements

public interface IMyAidl extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements cn.edu.hebust.aidldemo.IMyAidl {
private static final java.lang.String DESCRIPTOR = "cn.edu.hebust.aidldemo.IMyAidl";

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

/**
* Cast an IBinder object into an cn.edu.hebust.aidldemo.IMyAidl interface,
* generating a proxy if needed.
*/
public static cn.edu.hebust.aidldemo.IMyAidl asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof cn.edu.hebust.aidldemo.IMyAidl))) {
return ((cn.edu.hebust.aidldemo.IMyAidl) iin);
}
return new cn.edu.hebust.aidldemo.IMyAidl.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_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_add: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

private static class Proxy implements cn.edu.hebust.aidldemo.IMyAidl {
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.
* 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);
mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}

@Override
public int add(int num1, int num2) 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);
_data.writeInt(num1);
_data.writeInt(num2);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}

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

/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
* AIDL 通信的基本数据类型
*/
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;

public int add(int num1, int num2) throws android.os.RemoteException;
}


提供对外开放的Service

public class MyServer extends Service {

// 这里是对提供的Java AIDL文件的实现
// 通过onBind方法对外通信
private IMyAidl.Stub mStub = new IMyAidl.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}

// 我们需要调用的方法
@Override
public int add(int num1, int num2) throws RemoteException {
return num1 + num2;
}
};

@Nullable
@Override
public IBinder onBind(Intent intent) {
return mStub;
}
}


这个Service的声明如下,我们需要这个Service对外开放,并且使用单独的进程运行

<!--process 带有':'属性表示这个组件的进程是私有的,只要有有互端去启动,系统就会创建一个新的进程去运行-->
<!--不带表示这个进程时共享的–>-->
<service
android:name=".MyServer"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="cn.hebust.myservice" />
</intent-filter>
</service>


客户端的AIDL

这里客户端要拿到服务端的AIDL目录,并且实现对应的Java文件

// 直接在MainActivity中进行进行bindService
public class MainActivity extends AppCompatActivity {

private IMyAidl mStub;
// 使用一个Connection实现相互通信
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mStub = IMyAidl.Stub.asInterface(service);
try {
// 调用aidl interface的方法
int value = mStub.add(5, 5);
Toast.makeText(MainActivity.this, value + "", Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// 启动服务端程序
Intent intent = new Intent();
intent.setAction("cn.hebust.myservice");
ComponentName componentName = new ComponentName("cn.edu.hebust.aidldemo"
, "cn.edu.hebust.aidldemo.MyServer");
intent.setComponent(componentName);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: